Пример #1
0
    def cone(self):
        r"""
        Return the cone defined by `A`.

        This method is for debugging only. Assumes that the base ring
        is `\QQ`.

        OUTPUT:

        The cone defined by the inequalities as a
        :func:`~sage.geometry.polyhedron.constructor.Polyhedron`,
        using the PPL backend.

        EXAMPLES::

            sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
            sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
            sage: DD, _ = StandardAlgorithm(A).initial_pair()
            sage: DD.cone().Hrepresentation()
            (An inequality (-1, -1, 1) x + 0 >= 0,
             An inequality (0, 1, 1) x + 0 >= 0,
             An inequality (1, 0, 1) x + 0 >= 0)
        """
        from sage.geometry.polyhedron.constructor import Polyhedron
        assert self.problem.base_ring() == QQ  # required for PPL backend

        if not self.A:
            return Polyhedron(vertices=[[0] * self.problem.dim()],
                              backend='ppl')
        else:
            ieqs = [[0] + list(a) for a in self.A]
            return Polyhedron(ieqs=ieqs,
                              base_ring=self.problem.base_ring(),
                              backend='ppl')
Пример #2
0
    def verify(self):
        r"""
        Validate the double description pair.

        This method used the PPL backend to check that the double
        description pair is valid. An assertion is triggered if it is
        not. Does nothing if the base ring is not `\QQ`.

        EXAMPLES::

            sage: from sage.geometry.polyhedron.double_description import \
            ....:     DoubleDescriptionPair, Problem
            sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
            sage: alg = Problem(A)
            sage: DD = DoubleDescriptionPair(alg,
            ....:     [(1, 0, 3), (0, 1, 1), (-1, -1, 1)],
            ....:     [(2/3, -1/3, 1/3), (-1/3, 2/3, 1/3), (-1/3, -1/3, 1/3)])
            sage: DD.verify()
            Traceback (most recent call last):
            ...
                assert A_cone == R_cone
            AssertionError
        """
        from sage.geometry.polyhedron.constructor import Polyhedron
        if self.problem.base_ring() is not QQ:
            return
        A_cone = self.cone()
        R_cone = Polyhedron(vertices=[[self.zero] * self.problem.dim()],
                            rays=self.R,
                            base_ring=self.problem.base_ring(),
                            backend='ppl')
        assert A_cone == R_cone
        assert A_cone.n_inequalities() <= len(self.A)
        assert R_cone.n_rays() == len(self.R)
Пример #3
0
def arp_polyhedron(d=3):
    r"""
    Return the d-dimensional 1-cylinders of the ARP algorithm.

    EXAMPLES::

        sage: from slabbe.matrix_cocycle import arp_polyhedron
        sage: A,P,L = arp_polyhedron(3)
        sage: A.vertices_list()
        [[0, 0, 0], [1/2, 1/2, 0], [1/2, 1/4, 1/4], [1, 0, 0]]
        sage: P.vertices_list()
        [[0, 0, 0], [1/2, 1/2, 0], [1/2, 1/4, 1/4], [1/3, 1/3, 1/3]]

    ::

        sage: A,P,L = arp_polyhedron(4)
        sage: A.vertices_list()
        [[0, 0, 0, 0],
         [1/2, 1/2, 0, 0],
         [1/2, 1/6, 1/6, 1/6],
         [1/2, 1/4, 1/4, 0],
         [1, 0, 0, 0]]
        sage: P.vertices_list()
        [[0, 0, 0, 0],
         [1/2, 1/2, 0, 0],
         [1/2, 1/4, 1/4, 0],
         [1/2, 1/6, 1/6, 1/6],
         [1/4, 1/4, 1/4, 1/4],
         [1/3, 1/3, 1/3, 0]]

    ::

        sage: A,P,L = arp_polyhedron(5)
        sage: A.vertices_list()
        [[0, 0, 0, 0, 0],
         [1/2, 1/2, 0, 0, 0],
         [1/2, 1/8, 1/8, 1/8, 1/8],
         [1/2, 1/6, 1/6, 1/6, 0],
         [1/2, 1/4, 1/4, 0, 0],
         [1, 0, 0, 0, 0]]
        sage: P.vertices_list()
        [[0, 0, 0, 0, 0],
         [1/2, 1/2, 0, 0, 0],
         [1/2, 1/6, 1/6, 1/6, 0],
         [1/2, 1/8, 1/8, 1/8, 1/8],
         [1/2, 1/4, 1/4, 0, 0],
         [1/3, 1/3, 1/3, 0, 0],
         [1/5, 1/5, 1/5, 1/5, 1/5],
         [1/4, 1/4, 1/4, 1/4, 0]]
    """
    from sage.geometry.polyhedron.constructor import Polyhedron
    positive = [ [0]*i + [1] + [0]*(d-i) for i in range(1, d+1)]
    atmostone = [[1] + [-1]*d]
    ieq_arnoux = [[0]+[1]+[-1]*(d-1)]
    ieq_arnoux_not = [[0]+[-1]+[1]*(d-1)]
    ieq_sorted = [ [0]*i + [1,-1] + [0]*(d-i-1) for i in range(1,d)]
    A = Polyhedron(ieqs=positive + atmostone + ieq_sorted + ieq_arnoux)
    P = Polyhedron(ieqs=positive + atmostone + ieq_sorted + ieq_arnoux_not)
    L = Polyhedron(ieqs=positive + atmostone + ieq_sorted)
    return A,P,L
def is_Z3_convergent(a, b, c, d, e, f, g):
    r"""
    TESTS::

        sage: from surface_dynamics.misc.generalized_multiple_zeta_values import is_Z3_convergent

    Convergent examples::

        sage: assert is_Z3_convergent(2,0,2,2,0,0,0)
        sage: assert is_Z3_convergent(0,0,0,0,0,0,4)
        sage: assert is_Z3_convergent(1,0,0,1,0,0,2)
        sage: assert is_Z3_convergent(0,1,0,1,0,0,2)
        sage: assert is_Z3_convergent(0,1,0,0,0,1,2)

    Divergent examples::

        sage: assert not is_Z3_convergent(0,0,0,1,1,1,0)
        sage: assert not is_Z3_convergent(0,0,0,0,0,0,3)

    """
    from sage.geometry.polyhedron.constructor import Polyhedron
    x, y, z = ZZ['x,y,z'].gens()
    poly = x**a * y**b * z**c * (x + y)**d * (x + z)**e * (y + z)**f * (x + y +
                                                                        z)**g
    newton_polytope = Polyhedron(vertices=poly.exponents(),
                                 rays=[(-1, 0, 0), (0, -1, 0), (0, 0, -1)])
    V = newton_polytope.intersection(Polyhedron(rays=[(1, 1, 1)])).vertices()
    r = max(max(v.vector()) for v in V)
    return r > 1
Пример #5
0
    def populate_polyhedra(self):
        from sage.geometry.polyhedron.constructor import Polyhedron
        from sage.symbolic.ring import SR

        def get_vector(inequality, vars):
            coefficients = list(inequality.coefficient(var) for var in vars)
            constant = inequality - sum(c*v for c, v in zip(coefficients, vars))
            return [constant] + coefficients

        d = self.dimension()
        prefix = self.trees[0].PREFIX
        vars = list(SR(prefix + "{}".format(j)) for j in range(d+1))
        for tree in self.trees:
            others = list(self.trees)
            others.remove(tree)
            ineqs = [other.partition_cost() - tree.partition_cost()
                     for other in others] + vars
            ineq_matrix = [get_vector(ineq, vars) for ineq in ineqs]
            P = Polyhedron(ieqs=ineq_matrix)
            if self.is_disjoint():
                P = polyhedron_break_tie(P)
            tree.polyhedron = P

        nonnegative_orthant = Polyhedron(ieqs=[dd*(0,) + (1,) + (d+1-dd)*(0,)
                                               for dd in range(1, d+1+1)])
        assert all(A.polyhedron & nonnegative_orthant == A.polyhedron
                   for A in self.trees)
        if self.is_disjoint():
            assert all((A.polyhedron & B.polyhedron).is_empty()
                       for A in self.trees for B in self.trees if A != B)
Пример #6
0
    def verify(self):
        r"""
        Validate the double description pair.

        This method used the PPL backend to check that the double
        description pair is valid. An assertion is triggered if it is
        not. Does nothing if the base ring is not `\QQ`.

        EXAMPLES::

            sage: from sage.geometry.polyhedron.double_description import \
            ....:     DoubleDescriptionPair, Problem
            sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
            sage: alg = Problem(A)
            sage: DD = DoubleDescriptionPair(alg,
            ....:     [(1, 0, 3), (0, 1, 1), (-1, -1, 1)],
            ....:     [(2/3, -1/3, 1/3), (-1/3, 2/3, 1/3), (-1/3, -1/3, 1/3)])
            sage: DD.verify()
            Traceback (most recent call last):
            ...
                assert A_cone == R_cone
            AssertionError
        """
        from sage.geometry.polyhedron.constructor import Polyhedron
        if self.problem.base_ring() is not QQ:
            return
        A_cone = self.cone()
        R_cone = Polyhedron(vertices=[[self.zero] * self.problem.dim()], rays=self.R,
                            base_ring=self.problem.base_ring(), backend='ppl')
        assert A_cone == R_cone
        assert A_cone.n_inequalities() <= len(self.A)
        assert R_cone.n_rays() == len(self.R)
    def verify(self, inequalities, equations):
        """
        Compare result to PPL if the base ring is QQ.

        This method is for debugging purposes and compares the
        computation with another backend if available.

        INPUT:

        - ``inequalities``, ``equations`` -- see :class:`Hrep2Vrep`.

        EXAMPLES::

            sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Hrep2Vrep
            sage: H = Hrep2Vrep(QQ, 1, [(1,2)], [])
            sage: H.verify([(1,2)], [])
        """
        from sage.rings.all import QQ
        from sage.geometry.polyhedron.constructor import Polyhedron
        if self.base_ring is not QQ:
            return
        P = Polyhedron(vertices=self.vertices, rays=self.rays, lines=self.lines,
                       base_ring=QQ, ambient_dim=self.dim, backend='ppl')
        Q = Polyhedron(ieqs=inequalities, eqns=equations,
                       base_ring=QQ, ambient_dim=self.dim, backend='ppl')
        if (P != Q) or \
           (len(self.vertices) != P.n_vertices()) or \
           (len(self.rays) != P.n_rays()) or \
           (len(self.lines) != P.n_lines()):
            print('incorrect!', end="")
            print(Q.Vrepresentation())
            print(P.Hrepresentation())
def compute_monomials(R, nverts, dresverts):
    """Eq. A.8 from arXiv:1411.1418"""
    X = np.array(R.gens())
    Delta = Polyhedron(vertices=nverts)
    npoints = np.array(Delta.integral_points())
    P_expon = (npoints @ dresverts.T) + 1
    P_monoms = np.power(X, P_expon).prod(axis=1)
    return P_monoms
Пример #9
0
def cassaigne_polyhedron(d=3):
    r"""
    Return the d-dimensional 1-cylinders of the Cassaigne algorithm.

    (of the dual!)

    EXAMPLES::

        sage: from slabbe.matrix_cocycle import cassaigne_polyhedron
        sage: L,La,Lb = cassaigne_polyhedron(3)
        sage: L.vertices_list()
        [[0, 0, 0], [0, 1/2, 1/2], [1/3, 1/3, 1/3], [1/2, 1/2, 0]]
        sage: La.vertices_list()
        [[0, 0, 0], [0, 1/2, 1/2], [1/3, 1/3, 1/3], [1/4, 1/2, 1/4]]
        sage: Lb.vertices_list()
        [[0, 0, 0], [1/3, 1/3, 1/3], [1/2, 1/2, 0], [1/4, 1/2, 1/4]]

    ::

        sage: L,La,Lb = cassaigne_polyhedron(4)
        sage: L.vertices_list()
        [[0, 0, 0, 0],
         [0, 1/3, 1/3, 1/3],
         [1/3, 1/3, 1/3, 0],
         [1/4, 1/4, 1/4, 1/4],
         [1/5, 2/5, 1/5, 1/5],
         [1/5, 1/5, 2/5, 1/5]]

    ::

        sage: L,La,Lb = cassaigne_polyhedron(5)
        sage: L.vertices_list()
        [[0, 0, 0, 0, 0],
         [0, 1/4, 1/4, 1/4, 1/4],
         [1/4, 1/4, 1/4, 1/4, 0],
         [1/6, 1/6, 1/3, 1/6, 1/6],
         [1/5, 1/5, 1/5, 1/5, 1/5],
         [1/6, 1/3, 1/6, 1/6, 1/6],
         [1/7, 2/7, 2/7, 1/7, 1/7],
         [1/7, 2/7, 1/7, 2/7, 1/7],
         [1/7, 1/7, 2/7, 2/7, 1/7],
         [1/6, 1/6, 1/6, 1/3, 1/6]]
    """
    from sage.geometry.polyhedron.constructor import Polyhedron
    # [-1,7,3,4] represents the inequality 7x_1+3x_2+4x_3>= 1.
    positive = [ [0]*i + [1] + [0]*(d-i) for i in range(1, d+1)]
    atmostone = [[1] + [-1]*d]
    ai_lt_a1d = [[0]+[1]+[0]*(i-2)+[-1]+[0]*(d-i-1)+[1] for i in range(2,d)]
    ai_gt_a1 = [[0]+[-1]+[0]*(i-2)+[1]+[0]*(d-i-1)+[0] for i in range(2,d)]
    ai_gt_ad = [[0]+[0]+[0]*(i-2)+[1]+[0]*(d-i-1)+[-1] for i in range(2,d)]
    a1_gt_ad = [[0]+[1]+[0]*(d-2)+[-1]]
    a1_lt_ad = [[0]+[-1]+[0]*(d-2)+[1]]
    L = Polyhedron(ieqs=positive + atmostone + ai_lt_a1d + ai_gt_a1 + ai_gt_ad)
    La = Polyhedron(ieqs=positive+atmostone+ai_lt_a1d+ai_gt_a1+ai_gt_ad+a1_lt_ad)
    Lb = Polyhedron(ieqs=positive+atmostone+ai_lt_a1d+ai_gt_a1+ai_gt_ad+a1_gt_ad)
    return L, La, Lb
Пример #10
0
    def verify(self, inequalities, equations):
        """
        Compare result to PPL if the base ring is QQ.

        This method is for debugging purposes and compares the
        computation with another backend if available.

        INPUT:

        - ``inequalities``, ``equations`` -- see :class:`Hrep2Vrep`.

        EXAMPLES::

            sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Hrep2Vrep
            sage: H = Hrep2Vrep(QQ, 1, [(1,2)], [])
            sage: H.verify([(1,2)], [])
        """
        from sage.rings.all import QQ
        from sage.geometry.polyhedron.constructor import Polyhedron
        if self.base_ring is not QQ:
            return
        P = Polyhedron(vertices=self.vertices, rays=self.rays, lines=self.lines,
                       base_ring=QQ, ambient_dim=self.dim, backend='ppl')
        Q = Polyhedron(ieqs=inequalities, eqns=equations,
                       base_ring=QQ, ambient_dim=self.dim, backend='ppl')
        if (P != Q) or \
           (len(self.vertices) != P.n_vertices()) or \
           (len(self.rays) != P.n_rays()) or \
           (len(self.lines) != P.n_lines()):
            print 'incorrect!',
            print Q.Vrepresentation()
            print P.Hrepresentation()
def is_convergent(n, den):
    r"""
    TESTS::

        sage: import itertools
        sage: from surface_dynamics.misc.generalized_multiple_zeta_values import is_convergent
        sage: V = FreeModule(ZZ, 3)
        sage: va = V((1,0,0)); va.set_immutable()
        sage: vb = V((0,1,0)); vb.set_immutable()
        sage: vc = V((0,0,1)); vc.set_immutable()
        sage: vd = V((1,1,0)); vd.set_immutable()
        sage: ve = V((1,0,1)); ve.set_immutable()
        sage: vf = V((0,1,1)); vf.set_immutable()
        sage: vg = V((1,1,1)); vg.set_immutable()
        sage: gens = [va,vb,vc,vd,ve,vf,vg]
        sage: N = 0
        sage: for p in itertools.product([0,1,2], repeat=7): # optional: mzv
        ....:     if sum(map(bool,p)) == 3 and is_convergent(3, list(zip(gens,p))):
        ....:         print(p)
        ....:         N += 1
        (0, 0, 0, 0, 1, 1, 2)
        (0, 0, 0, 0, 1, 2, 1)
        (0, 0, 0, 0, 1, 2, 2)
        (0, 0, 0, 0, 2, 1, 1)
        (0, 0, 0, 0, 2, 1, 2)
        (0, 0, 0, 0, 2, 2, 1)
        (0, 0, 0, 0, 2, 2, 2)
        (0, 0, 0, 1, 0, 1, 2)
        ...
        (2, 0, 2, 0, 0, 2, 0)
        (2, 0, 2, 2, 0, 0, 0)
        (2, 1, 0, 0, 0, 0, 2)
        (2, 1, 0, 0, 0, 2, 0)
        (2, 2, 0, 0, 0, 0, 2)
        (2, 2, 0, 0, 0, 2, 0)
        (2, 2, 0, 0, 2, 0, 0)
        (2, 2, 2, 0, 0, 0, 0)
        sage: print(N) # optional: mzv
        125
    """
    from sage.geometry.polyhedron.constructor import Polyhedron
    from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing

    assert all(len(v) == n for v, p in den), (n, den)

    # TODO: fast code path

    R = PolynomialRing(QQ, 'x', n)
    x = R.gens()
    den_poly = prod(linear_form(R, v)**p for v, p in den)
    newton_polytope = Polyhedron(vertices=den_poly.exponents(),
                                 rays=negative_rays(n))
    V = newton_polytope.intersection(Polyhedron(rays=[[1] * n])).vertices()
    r = max(max(v.vector()) for v in V)
    return r > 1
Пример #12
0
def cone_triangulate(C, hyperplane=None):
    r"""
    Triangulation of rational cone contained in the positive quadrant.

    EXAMPLES::

        sage: from surface_dynamics.misc.linalg import cone_triangulate
        sage: P = Polyhedron(rays=[(1,0,0),(0,1,0),(1,0,1),(0,1,1)])
        sage: list(cone_triangulate(P)) # random
        [[(0, 1, 1), (0, 1, 0), (1, 0, 0)], [(0, 1, 1), (1, 0, 1), (1, 0, 0)]]
        sage: len(_)
        2

        sage: rays = [(0, 1, 0, -1, 0, 0),
        ....: (1, 0, -1, 0, 0, -1),
        ....: (0, 1, -1, 0, 0, -1),
        ....: (0, 0, 1, 0, 0, 0),
        ....: (0, 0, 0, 1, 0, -1),
        ....: (1, -1, 0, 0, 1, -1),
        ....: (0, 0, 0, 0, 1, -1),
        ....: (0, 0, 1, -1, 1, 0),
        ....: (0, 0, 1, -1, 0, 0),
        ....: (0, 0, 1, 0, -1, 0),
        ....: (0, 0, 0, 1, -1, -1),
        ....: (1, -1, 0, 0, 0, -1),
        ....: (0, 0, 0, 0, 0, -1)]
        sage: P = Polyhedron(rays=rays)
        sage: list(cone_triangulate(P, hyperplane=(1, 2, 3, -1, 0, -5))) # random
        [[(0, 0, 0, 0, 0, -1),
          (0, 0, 0, 0, 1, -1),
          (0, 0, 0, 1, -1, -1),
          (0, 0, 1, 0, 0, 0),
          (0, 1, -1, 0, 0, -1),
          (1, -1, 0, 0, 1, -1)],
          ...
          (0, 0, 1, 0, 0, 0),
          (0, 1, -1, 0, 0, -1),
          (0, 1, 0, -1, 0, 0),
          (1, -1, 0, 0, 1, -1),
          (1, 0, -1, 0, 0, -1)]]
        sage: len(_)
        16
    """
    rays = [r.vector() for r in C.rays()]
    dim = len(rays[0])
    if hyperplane is None:
        hyperplane = [1] * dim
    scalings = [sum(x * h for x, h in zip(r, hyperplane)) for r in rays]
    assert all(s > 0 for s in scalings)
    normalized_rays = [r / s for r, s in zip(rays, scalings)]
    P = Polyhedron(vertices=normalized_rays)
    for t in P.triangulate():
        simplex = [P.Vrepresentation(i).vector() for i in t]
        yield [(r / gcd(r)).change_ring(ZZ) for r in simplex]
Пример #13
0
def family_two(n, backend=None):
    r"""
    Return the vector configuration of the simplicial arrangement
    `A(n,1)` from the family `\mathcal R(1)` in Grunbaum's list [Gru]_.

    The arrangement will have an ``n`` hyperplanes, with ``n`` even, consisting
    of the edges of the regular `n/2`-gon and the `n/2` lines of 
    mirror symmetry.

    INPUT:

    - ``n`` -- integer. ``n`` `\geq 6`. The number of lines in the arrangement.
    
    - ``backend`` -- string (default = ``None``). The backend to use.

    OUTPUT:

    A vector configuration.

    EXAMPLES::

        sage: from cn_hyperarr.infinite_families import *
        sage: pf = family_two(8,'normaliz'); pf   # optional - pynormaliz
        Vector configuration of 8 vectors in dimension 3

    The number of lines must be even::

        sage: pf3 = family_two(3,'normaliz');     # optional - pynormaliz
        Traceback (most recent call last):
        ...
        AssertionError: n must be even

    The number of lines must be at least 6::

        sage: pf4 = family_two(4,'normaliz')      # optional - pynormaliz
        Traceback (most recent call last):
        ...
        ValueError: n (=2) must be an integer greater than 2
    """
    assert n % 2 == 0, "n must be even"
    reg_poly = polytopes.regular_polygon(n / QQ(2), backend='normaliz')
    reg_cone = Polyhedron(
        rays=[list(v.vector()) + [1] for v in reg_poly.vertices()],
        backend=backend)
    vecs = [h.A() for h in reg_cone.Hrepresentation()]

    z = QQbar.zeta(n)
    vecs += [[(z**k).real(), (z**k).imag(), 0] for k in range(n / QQ(2))]
    return VectorConfiguration(vecs, backend=backend)
Пример #14
0
def taut_rays(tri, angle):
    # get the extreme rays of the taut cone - note that the returned
    # vectors are non-negative because they "point up"
    N = edge_equation_matrix_taut(tri, angle)
    N = Matrix(N)
    dim = N.dimensions()[1]
    elem_ieqs = [[0] + list(elem_vector(i, dim)) for i in range(dim)]
    N_rows = [v.list() for v in N.rows()]
    N_eqns = [[0] + v for v in N_rows]
    P = Polyhedron(ieqs = elem_ieqs, eqns = N_eqns)

    rays = [ray.vector() for ray in P.rays()]
    for ray in rays:
        assert all(a.is_integer() for a in ray)
    # all of the entries are integers, represented in QQ, so we clean them.
    return [vector(ZZ(a) for a in ray) for ray in rays]
Пример #15
0
def platonic_dodecahedron():
    r"""Produce a triple consisting of a polyhedral version of the platonic dodecahedron,
    the associated cone surface, and a ConeSurfaceToPolyhedronMap from the surface
    to the polyhedron.

    EXAMPLES::

    sage: from flatsurf.geometry.polyhedra import platonic_dodecahedron
    sage: polyhedron,surface,surface_to_polyhedron = platonic_dodecahedron()
    sage: TestSuite(surface).run()
    r"""
    vertices = []
    phi = AA(1 + sqrt(5)) / 2
    F = NumberField(phi.minpoly(), "phi", embedding=phi)
    phi = F.gen()
    for x in range(-1, 3, 2):
        for y in range(-1, 3, 2):
            for z in range(-1, 3, 2):
                vertices.append(vector(F, (x, y, z)))
    for x in range(-1, 3, 2):
        for y in range(-1, 3, 2):
            vertices.append(vector(F, (0, x * phi, y / phi)))
            vertices.append(vector(F, (y / phi, 0, x * phi)))
            vertices.append(vector(F, (x * phi, y / phi, 0)))
    scale = AA(2 / sqrt(1 + (phi - 1)**2 + (1 / phi - 1)**2))
    p = Polyhedron(vertices=vertices)
    s, m = polyhedron_to_cone_surface(p, scaling_factor=scale)
    return p, s, m
Пример #16
0
def platonic_icosahedron():
    r"""Produce a triple consisting of a polyhedral version of the platonic icosahedron,
    the associated cone surface, and a ConeSurfaceToPolyhedronMap from the surface
    to the polyhedron.

    EXAMPLES::

    sage: from flatsurf.geometry.polyhedra import platonic_icosahedron
    sage: polyhedron,surface,surface_to_polyhedron = platonic_icosahedron()
    sage: TestSuite(surface).run()
    r"""
    vertices = []
    phi = AA(1 + sqrt(5)) / 2
    F = NumberField(phi.minpoly(), "phi", embedding=phi)
    phi = F.gen()
    for i in range(3):
        for s1 in range(-1, 3, 2):
            for s2 in range(-1, 3, 2):
                p = 3 * [None]
                p[i] = s1 * phi
                p[(i + 1) % 3] = s2
                p[(i + 2) % 3] = 0
                vertices.append(vector(F, p))
    p = Polyhedron(vertices=vertices)

    s, m = polyhedron_to_cone_surface(p)
    return p, s, m
Пример #17
0
def random_interior_point(self, a=10, integer=False):
    r"""
    Return a random interior point of a polytope.

    INPUT:

    - ``a`` -- number, amplitude of random deplacement in the direction of each
      ray.
    - ``integer`` -- bool, whether the output must be with integer
      coordinates

    EXEMPLES::

        sage: from slabbe.combinat import random_interior_point
        sage: p = polytopes.hypercube(3)
        sage: p = p + vector([20,0,0])
        sage: p.center()
        (20, 0, 0)
        sage: random_interior_point(p)     # random
        (19.33174562788114, -0.5428002756082744, -0.3568284089832092)
        sage: random_interior_point(p)     # random
        (20.039169786976075, -0.4121594862234468, -0.05623023234688396)
        sage: random_interior_point(p, integer=True)     # random
        (21, 0, 0)
    """
    from sage.geometry.polyhedron.constructor import Polyhedron
    L = list(self.vertices())
    L.extend(a * random() * ray.vector() for ray in self.rays())
    P = Polyhedron(L)
    return random_interior_point_compact_polytope(P)
Пример #18
0
def opposite_polyhedron(P, base_ring=None):
    r"""Generate the polyhedron whose vertices are oppositve to a given one.

    The opposite polyhedron `-P` is defined as the polyhedron such that `x \in -P` if and only if `-x \in P`. 

    INPUT:

    * ``P`` - an object of class Polyhedron.

    * ``base_ring`` - (default: that of P). The ``base_ring`` passed to construct `-P`.

    OUTPUT:

    A polyhedron whose vertices are opposite to those of `P`.

    EXAMPLES::

        sage: from polyhedron_tools.misc import BoxInfty, opposite_polyhedron
        sage: P = BoxInfty([1,1], 0.5)
        sage: minusP = opposite_polyhedron(P)
        sage: P.plot(aspect_ratio=1) + minusP.plot()    # not tested (plot)

    TO-DO:

    The possibility to receive P in matrix form `(A, b)`.
    """
    if base_ring is None:
        base_ring = P.base_ring()

    return Polyhedron(vertices=[-1 * vector(v) for v in P.vertices_list()],
                      base_ring=base_ring)
Пример #19
0
    def intersection(self, other):
        r"""
        The intersection of ``self`` with ``other``.

        INPUT:

        - ``other`` -- a hyperplane, a polyhedron, or something that
          defines a polyhedron

        OUTPUT:

        A polyhedron.

        EXAMPLES::

            sage: H.<x,y,z> = HyperplaneArrangements(QQ)
            sage: h = x + y + z - 1
            sage: h.intersection(x - y)
            A 1-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex and 1 line
            sage: h.intersection(polytopes.cube())
            A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices
        """
        from sage.geometry.polyhedron.base import is_Polyhedron
        from sage.geometry.polyhedron.constructor import Polyhedron
        if not is_Polyhedron(other):
            try:
                other = other.polyhedron()
            except AttributeError:
                other = Polyhedron(other)
        return self.polyhedron().intersection(other)
Пример #20
0
def polyhedron_break_tie(polyhedron, undo=False):
    from sage.geometry.polyhedron.constructor import Polyhedron

    if polyhedron.equations():
        raise NotImplementedError
    return Polyhedron(ieqs=[break_tie(tuple(ieq), undo=undo)
                            for ieq in polyhedron.inequalities()])
Пример #21
0
def split_polyhedra(dim):
    r"""
    ::

        sage: from partitioner import split_polyhedra, repr_pretty_Hrepresentation

        sage: for P in split_polyhedra(2):
        ....:     print(repr_pretty_Hrepresentation(P, strict_inequality=True,
        ....:                                       prefix='s'))
        s1 > s0
        s0 >= s1

        sage: for P in split_polyhedra(3):
        ....:     print(repr_pretty_Hrepresentation(P, strict_inequality=True,
        ....:                                       prefix='s'))
        s1 >= s0, s2 > s1
        s2 > s0, s1 >= s2
        s2 > s0, s0 > s1
        s2 > s1, s0 >= s2
        s1 >= s0, s0 >= s2
        s1 >= s2, s0 > s1

        sage: for P in split_polyhedra(4):
        ....:     print(repr_pretty_Hrepresentation(P, strict_inequality=True,
        ....:                                       prefix='s'))
        s1 >= s0, s2 > s1, s3 > s2
        s1 >= s0, s3 > s1, s2 >= s3
        s2 >= s0, s3 > s1, s1 >= s2
        s2 >= s0, s3 > s2, s1 >= s3
        s3 > s0, s2 > s1, s1 >= s3
        s3 > s0, s2 >= s3, s1 >= s2
        s2 >= s0, s3 > s2, s0 > s1
        s3 > s0, s2 >= s3, s0 > s1
        s3 > s0, s2 > s1, s0 > s2
        s2 > s1, s3 > s2, s0 >= s3
        s2 >= s0, s3 > s1, s0 >= s3
        s3 > s1, s2 >= s3, s0 > s2
        s1 >= s0, s3 > s1, s0 > s2
        s3 > s0, s1 >= s3, s0 > s2
        s3 > s0, s1 >= s2, s0 > s1
        s3 > s1, s1 >= s2, s0 >= s3
        s1 >= s0, s3 > s2, s0 >= s3
        s3 > s2, s1 >= s3, s0 > s1
        s1 >= s0, s2 > s1, s0 >= s3
        s2 >= s0, s1 >= s2, s0 >= s3
        s2 >= s0, s1 >= s3, s0 > s1
        s2 > s1, s1 >= s3, s0 > s2
        s1 >= s0, s2 >= s3, s0 > s2
        s2 >= s3, s1 >= s2, s0 > s1
    """
    from sage.combinat.permutation import Permutations
    from sage.geometry.polyhedron.constructor import Polyhedron

    return iter(
        polyhedron_break_tie(
            Polyhedron(
                ieqs=[tuple(1 if i==b else (-1 if i==a else 0)
                            for i in range(dim+1))
                      for a, b in zip(pi[:-1], pi[1:])]))
        for pi in Permutations(dim))
Пример #22
0
    def polytope(self, P=None):
        """
        Return a polytope of ``self``.

        INPUT:

        - ``P`` -- (optional) a space to realize the polytope; default is
          the weight lattice realization of the crystal

        EXAMPLES::

            sage: MV = crystals.infinity.MVPolytopes(['C', 3])
            sage: b = MV.module_generators[0].f_string([3,2,3,2,1])
            sage: P = b.polytope(); P
            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 6 vertices
            sage: P.vertices()
            (A vertex at (0, 0, 0),
             A vertex at (0, 1, -1),
             A vertex at (0, 1, 1),
             A vertex at (1, -1, 0),
             A vertex at (1, 1, -2),
             A vertex at (1, 1, 2))
        """
        if P is None:
            P = self.parent().weight_lattice_realization()

        from sage.geometry.polyhedron.constructor import Polyhedron
        return Polyhedron([v.to_vector() for v in self._polytope_vertices(P)])
Пример #23
0
    def line_vertices(self):
        r"""
        Return the vertices for each line in a 3-d acyclic vector_configuration.

        NOTE:

        An acyclic vector configuration corresponds to the normal vectors of
        a hyperplane arrangement with a selected base region.

        OUTPUT:

        A list of pairs.

        EXAMPLES::

            sage: from cn_hyperarr.vector_classes import *
            sage: vc = VectorConfiguration([[1,0,0],[0,1,0],[0,0,1],[1,1,0],[0,1,1],[1,1,1]])
            sage: vc.line_vertices()
            [(0, 1), (1, 2), (2, 3), (0, 4)]

        The vectors [-1,0,1] and [1,0,1] are the vertices of the line containing
        [0,0,1]::

            sage: vc = VectorConfiguration([[0,0,1],[-1,0,1],[1,0,1]])
            sage: vc.line_vertices()
            [(1, 2)]
        """
        assert self.is_acyclic(), "The vector configuration should be acyclic"
        nb_pts = self.n_vectors()
        cocircuits = self.three_dim_cocircuits()
        list_verts = []

        for coc in cocircuits:
            zero_indices = coc[1]
            if len(zero_indices) > 2:
                the_cone = Polyhedron(rays=[self[j] for j in zero_indices],
                                      backend=self._backend)
                the_verts = tuple([
                    _ for _ in zero_indices
                    if not the_cone.relative_interior_contains(self[_])
                ])
                assert len(the_verts) == 2, "problem with the cocircuits"
                if the_verts not in list_verts:
                    list_verts += [the_verts]

        return list_verts
Пример #24
0
def is_union_convex(t):
    r"""
    Return whether the union of the polyhedrons is convex.

    INPUT:

    - ``t`` -- list of polyhedron

    EXAMPLES::

        sage: from slabbe.polyhedron_partition import is_union_convex
        sage: h = 1/2
        sage: p = Polyhedron([(0,h),(0,1),(h,1)])
        sage: q = Polyhedron([(0,0), (0,h), (h,1), (1,1), (1,h), (h,0)])
        sage: r = Polyhedron([(h,0), (1,0), (1,h)])
        sage: is_union_convex((p,q,r))
        True
        sage: is_union_convex((p,q))
        True
        sage: is_union_convex((p,r))
        False

    Here we need to consider the three at the same time to get a convex
    union::

        sage: h = 1/5
        sage: p = Polyhedron([(0,0),(h,1-h),(0,1)])
        sage: q = Polyhedron([(0,1), (h,1-h), (1,1)])
        sage: r = Polyhedron([(0,0), (h,1-h), (1,1), (1,0)])
        sage: is_union_convex((p,q))
        False
        sage: is_union_convex((p,r))
        False
        sage: is_union_convex((q,r))
        False
        sage: is_union_convex((p,q,r))
        True
    """
    if not t:
        return True
    base_ring = t[0].base_ring()
    vertices = sum((p.vertices() for p in t), tuple())
    r = Polyhedron(vertices, base_ring=base_ring)
    return r.volume() == sum(p.volume() for p in t)
Пример #25
0
def deformation_cone(v):
    r"""
    Return the deformation cone of the given vector ``v``

    EXAMPLES::

        sage: from surface_dynamics.misc.linalg import deformation_cone
        sage: K.<sqrt2> = QuadraticField(2)
        sage: v3 = vector([sqrt2, 1, 1+sqrt2])
        sage: P = deformation_cone(v3)
        sage: P
        A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex and 2 rays
        sage: P.rays_list()
        [[1, 0, 1], [0, 1, 1]]
    """
    V = deformation_space(v)
    P = Polyhedron(lines=deformation_space(v).basis())
    B = Polyhedron(rays=(QQ**V.degree()).basis())
    return P.intersection(B)
    def _an_element_(self):
        """
        Returns a Newton polygon (which is the empty one)

        TESTS:

            sage: from sage.geometry.newton_polygon import NewtonPolygon
            sage: NewtonPolygon._an_element_()
            Empty Newton polygon
        """
        return self(Polyhedron(base_ring=self.base_ring(), ambient_dim=2))
Пример #27
0
    def _borcherds_product_polyhedron(self, pole_order, prec, verbose=False):
        r"""
        Construct a polyhedron representing a cone of Heegner divisors. For internal use in the methods borcherds_input_basis() and borcherds_input_Qbasis().

        INPUT:
        - ``pole_order`` -- pole order
        - ``prec`` -- precision

        OUTPUT: a tuple consisting of an integral matrix M, a Polyhedron p, and a WeilRepModularFormsBasis X

        EXAMPLES::

            sage: from weilrep import *
            sage: m = ParamodularForms(5)
            sage: m._borcherds_product_polyhedron(1/4, 5)[1]
            A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex and 2 rays
        """
        S = self.gram_matrix()
        wt = self.input_wt()
        w = self.weilrep()
        rds = w.rds()
        norm_dict = w.norm_dict()
        X = w.nearly_holomorphic_modular_forms_basis(wt,
                                                     pole_order,
                                                     prec,
                                                     verbose=verbose)
        N = len([g for g in rds if not norm_dict[tuple(g)]])
        v_list = w.coefficient_vector_exponents(0,
                                                1,
                                                starting_from=-pole_order,
                                                include_vectors=True)
        exp_list = [v[1] for v in v_list]
        v_list = [vector(v[0]) for v in v_list]
        positive = [None] * len(exp_list)
        zero = vector([0] * (len(exp_list) + 1))
        M = matrix([
            x.coefficient_vector(starting_from=-pole_order, ending_with=0)[:-N]
            for x in X
        ])
        vs = M.transpose().kernel().basis()
        for i, n in enumerate(exp_list):
            ieq = copy(zero)
            ieq[i + 1] = 1
            for j, m in enumerate(exp_list[:i]):
                N = sqrt(m / n)
                if N in ZZ:
                    v1 = v_list[i]
                    v2 = v_list[j]
                    ieq[j + 1] = denominator(v1 * N -
                                             v2) == 1 or denominator(v1 * N +
                                                                     v2) == 1
            positive[i] = ieq
        p = Polyhedron(ieqs=positive, eqns=[vector([0] + list(v)) for v in vs])
        return M, p, X
Пример #28
0
def deformation_cone(v):
    r"""
    Return the deformation cone of the given vector ``v``

    EXAMPLES::

        sage: from surface_dynamics.misc.linalg import deformation_cone
        sage: K.<sqrt2> = QuadraticField(2)
        sage: v3 = vector([sqrt2, 1, 1+sqrt2])
        sage: P = deformation_cone(v3)
        sage: P
        A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex and 2 rays
        sage: P.rays_list()
        [[1, 0, 1], [0, 1, 1]]
    """
    from sage.rings.all import QQ
    from sage.geometry.polyhedron.constructor import Polyhedron
    V = deformation_space(v)
    P = Polyhedron(lines=deformation_space(v).basis())
    B = Polyhedron(rays=(QQ**V.degree()).basis())
    return P.intersection(B)
Пример #29
0
    def verify(self, vertices, rays, lines):
        """
        Compare result to PPL if the base ring is QQ.

        This method is for debugging purposes and compares the
        computation with another backend if available.

        INPUT:

        - ``vertices``, ``rays``, ``lines`` -- see :class:`Vrep2Hrep`.

        EXAMPLES::

            sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Vrep2Hrep
            sage: vertices = [(-1/2,0)]
            sage: rays = [(-1/2,2/3), (1/2,-1/3)]
            sage: lines = []
            sage: V2H = Vrep2Hrep(QQ, 2, vertices, rays, lines)
            sage: V2H.verify(vertices, rays, lines)
        """
        from sage.rings.all import QQ
        from sage.geometry.polyhedron.constructor import Polyhedron
        if self.base_ring is not QQ:
            return
        P = Polyhedron(vertices=vertices, rays=rays, lines=lines,
                       base_ring=QQ, ambient_dim=self.dim)
        trivial = [self.base_ring.one()] + [self.base_ring.zero()] * self.dim   # always true equation
        Q = Polyhedron(ieqs=self.inequalities + [trivial], eqns=self.equations,
                       base_ring=QQ, ambient_dim=self.dim)
        if not P == Q:
            print 'incorrect!', P, Q
            print Q.Vrepresentation()
            print P.Hrepresentation()
Пример #30
0
def experiment():
    rank = 5
    level = 4
    num_points = 11

    client = cbc.CBClient()
    liealg = cbd.TypeALieAlgebra(rank, store_fusion=True, exact=True)
    rays = []
    wts = []
    ranks = []
    for wt in liealg.get_weights(level):
        if wt == tuple([0 for x in range(0, rank)]):
            continue
        cbb = cbd.SymmetricConformalBlocksBundle(client, liealg, wt,
                                                 num_points, level)
        if cbb.get_rank() == 0:
            continue
        divisor = cbb.get_symmetrized_divisor()
        if divisor == [
                sage.Rational(0) for x in range(0, num_points // 2 - 1)
        ]:
            continue
        rays = rays + [divisor]
        wts = wts + [wt]
        ranks = ranks + [cbb.get_rank()]
        #print(wt, cbb.get_rank(), divisor)

    p = Polyhedron(rays=rays, base_ring=RationalField(), backend="cdd")
    extremal_rays = [list(v.vector()) for v in p.Vrepresentation()]
    c = Cone(p)
    print("Extremal rays:")
    for i in range(0, len(rays)):
        ray = rays[i]
        wt = wts[i]
        rk = ranks[i]
        if ray in extremal_rays:
            print(rk, wt, ray)
Пример #31
0
def platonic_tetrahedron():
    r"""Produce a triple consisting of a polyhedral version of the platonic tetrahedron,
    the associated cone surface, and a ConeSurfaceToPolyhedronMap from the surface
    to the polyhedron.

    EXAMPLES::

    sage: from flatsurf.geometry.polyhedra import platonic_tetrahedron
    sage: polyhedron,surface,surface_to_polyhedron = platonic_tetrahedron()
    sage: TestSuite(surface).run()
    r"""
    vertices = []
    for x in range(-1, 3, 2):
        for y in range(-1, 3, 2):
            vertices.append(vector(QQ, (x, y, x * y)))
    p = Polyhedron(vertices=vertices)
    s, m = polyhedron_to_cone_surface(p, scaling_factor=AA(1 / sqrt(2)))
    return p, s, m
Пример #32
0
def random_interior_point_compact_polytope(self,
                                           uniform='simplex',
                                           integer=False):
    r"""
    Return a random interior point of a compact polytope.

    INPUT:

    - ``uniform`` -- ``'points'`` (slow) or ``'simplex'`` (fast), whether
      to take the probability uniformly with respect to the set of integral
      points or with respect to the simplexes.
    - ``integer`` -- bool, whether the output must be with integer
      coordinates

    EXEMPLES::

        sage: from slabbe.combinat import random_interior_point_compact_polytope
        sage: p = polytopes.hypercube(3)
        sage: p = p + vector([30,20,10])
        sage: p.center()
        (30, 20, 10)
        sage: random_interior_point_compact_polytope(p)     # random
        (19.33174562788114, -0.5428002756082744, -0.3568284089832092)
        sage: random_interior_point_compact_polytope(p)     # random
        (20.039169786976075, -0.4121594862234468, -0.05623023234688396)
        sage: random_interior_point_compact_polytope(p, integer=True) # random
        (30, 19, 9)
    """
    assert self.is_compact(), "input is not compact"
    from sage.geometry.polyhedron.constructor import Polyhedron
    triangulation = self.triangulate()
    T = []
    for simplex_indices in self.triangulate():
        simplex_vertices = [self.Vrepresentation(i) for i in simplex_indices]
        simplex = Polyhedron(simplex_vertices)
        T.append(simplex)
    if uniform == 'points':
        v = [p.integral_points_count() for p in T]  # slow
        i = non_uniform_randint(v)
    elif uniform == 'simplex':
        i = randrange(len(T))
    else:
        raise ValueError('unknown value for uniform(={})'.format(uniform))
    return random_interior_point_simplex(T[i], integer=integer)
Пример #33
0
    def permutahedron(self, point=None):
        r"""
        Return the permutahedron of ``self``.

        This is the convex hull of the point ``point`` in the weight
        basis under the action of ``self`` on the underlying vector
        space `V`.

        INPUT:

        - ``point`` -- optional, a point given by its coordinates in
          the weight basis (default is `(1, 1, 1, \ldots)`)

        .. NOTE::

            The result is expressed in the root basis coordinates.

        EXAMPLES::

            sage: W = ReflectionGroup(['A',3])                          # optional - gap3
            sage: W.permutahedron()                                     # optional - gap3
            A 3-dimensional polyhedron in QQ^3 defined as the convex hull
            of 24 vertices

            sage: W = ReflectionGroup(['A',3],['B',2])                  # optional - gap3
            sage: W.permutahedron()                                     # optional - gap3
            A 5-dimensional polyhedron in QQ^5 defined as the convex hull of 192 vertices

        TESTS::

            sage: W = ReflectionGroup(['A',3])                          # optional - gap3
            sage: W.permutahedron([3,5,8])                              # optional - gap3
            A 3-dimensional polyhedron in QQ^3 defined as the convex hull
            of 24 vertices
        """
        n = self.rank()
        weights = self.fundamental_weights()
        if point is None:
            point = [1] * n
        v = sum(point[i] * wt for i, wt in enumerate(weights))
        from sage.geometry.polyhedron.constructor import Polyhedron
        return Polyhedron(vertices=[v*w.to_matrix() for w in self])
Пример #34
0
def platonic_octahedron():
    r"""Produce a triple consisting of a polyhedral version of the platonic octahedron,
    the associated cone surface, and a ConeSurfaceToPolyhedronMap from the surface
    to the polyhedron.

    EXAMPLES::

    sage: from flatsurf.geometry.polyhedra import platonic_octahedron
    sage: polyhedron,surface,surface_to_polyhedron = platonic_octahedron()
    sage: TestSuite(surface).run()
    r"""
    vertices = []
    for i in range(3):
        temp = vector(QQ, [1 if k == i else 0 for k in range(3)])
        for j in range(-1, 3, 2):
            vertices.append(j * temp)
    octahedron = Polyhedron(vertices=vertices)
    surface,surface_to_octahedron = \
        polyhedron_to_cone_surface(octahedron,scaling_factor=AA(sqrt(2)))
    return octahedron, surface, surface_to_octahedron
Пример #35
0
    def plot_walls(self, walls):
        r"""
        Plot ``walls``, i.e. 2-d cones, and their labels.

        Ray generators must be specified during construction or using
        :meth:`set_rays` before calling this method and these specified
        ray generators will be used in conjunction with
        :meth:`~sage.geometry.cone.ConvexRationalPolyhedralCone.ambient_ray_indices`
        of ``walls``.

        INPUT:

        - ``walls`` -- a list of 2-d cones.

        OUTPUT:

        - a plot.

        EXAMPLES::

            sage: quadrant = Cone([(1,0), (0,1)])
            sage: from sage.geometry.toric_plotter import ToricPlotter
            sage: tp = ToricPlotter(dict(), 2, quadrant.rays())
            sage: tp.plot_walls([quadrant])
            Graphics object consisting of 2 graphics primitives
            
        Let's also check that the truncating polyhedron is functioning
        correctly::

            sage: tp = ToricPlotter({"mode": "box"}, 2, quadrant.rays())
            sage: tp.plot_walls([quadrant])
            Graphics object consisting of 2 graphics primitives
        """
        result = Graphics()
        if not walls or not self.show_walls:
            return result
        rays = self.rays
        extra_options = self.extra_options
        mode = self.mode
        alpha = self.wall_alpha
        colors = color_list(self.wall_color, len(walls))
        zorder = self.wall_zorder
        if mode == "box":
            if self.dimension <= 2:
                ieqs = [(self.xmax, -1, 0), (- self.xmin, 1, 0),
                        (self.ymax, 0, -1), (- self.ymin, 0, 1)]
            else:
                ieqs = [(self.xmax, -1, 0, 0), (- self.xmin, 1, 0, 0),
                        (self.ymax, 0, -1, 0), (- self.ymin, 0, 1, 0),
                        (self.zmax, 0, 0, -1), (- self.zmin, 0, 0, 1)]
            box = Polyhedron(ieqs=ieqs, base_ring=RDF)
            for wall, color in zip(walls, colors):
                result += box.intersection(wall.polyhedron()).render_solid(
                    alpha=alpha, color=color, zorder=zorder, **extra_options)
        elif mode == "generators":
            origin = self.origin
            for wall, color in zip(walls, colors):
                vertices = [rays[i] for i in wall.ambient_ray_indices()]
                vertices.append(origin)
                result += Polyhedron(vertices=vertices, base_ring=RDF).render_solid(
                    alpha=alpha, color=color, zorder=zorder, **extra_options)
        label_sectors = []
        round = mode == "round"
        for wall, color in zip(walls, colors):
            S = wall.linear_subspace()
            lsd = S.dimension()
            if lsd == 0:    # Strictly convex wall
                r1, r2 = (rays[i] for i in wall.ambient_ray_indices())
            elif lsd == 1:  # wall is a half-plane
                for i, ray in zip(wall.ambient_ray_indices(), wall.rays()):
                    if ray in S:
                        r1 = rays[i]
                    else:
                        r2 = rays[i]
                if round:
                    # Plot one "extra" sector
                    result += sector(- r1, r2,
                      alpha=alpha, color=color, zorder=zorder, **extra_options)
            else:           # wall is a plane
                r1, r2 = S.basis()
                r1 = vector(RDF, r1)
                r1 = r1 / r1.norm() * self.radius
                r2 = vector(RDF, r2)
                r2 = r2 / r2.norm() * self.radius
                if round:
                    # Plot three "extra" sectors
                    result += sector(r1, - r2,
                      alpha=alpha, color=color, zorder=zorder, **extra_options)
                    result += sector(- r1, r2,
                      alpha=alpha, color=color, zorder=zorder, **extra_options)
                    result += sector(- r1, - r2,
                      alpha=alpha, color=color, zorder=zorder, **extra_options)
            label_sectors.append([r1, r2])
            if round:
                result += sector(r1, r2,
                    alpha=alpha, color=color, zorder=zorder, **extra_options)
        result += self.plot_labels(self.wall_label,
                    [sum(label_sector) / 3 for label_sector in label_sectors])
        return result
Пример #36
0
def RandomTriangulation(n, embed=False, base_ring=QQ):
    """
    Returns a random triangulation on n vertices.

    A triangulation is a planar graph all of whose faces are
    triangles (3-cycles).

    The graph is built by independently generating `n` points
    uniformly at random on the surface of a sphere, finding the
    convex hull of those points, and then returning the 1-skeleton
    of that polyhedron.

    INPUT:

    - ``n`` -- number of vertices (recommend `n \ge 3`)

    - ``embed`` -- (optional, default ``False``) whether to use the
      stereographic point projections to draw the graph.

    - ``base_ring`` -- (optional, default ``QQ``) specifies the field over
      which to do the intermediate computations. The default setting is slower,
      but works for any input; one can instead use ``RDF``, but this occasionally
      fails due to loss of precision, as mentioned on :trac:10276.

    EXAMPLES::

        sage: g = graphs.RandomTriangulation(10)
        sage: g.is_planar()
        True
        sage: g.num_edges() == 3*g.order() - 6
        True

    TESTS::

        sage: for i in range(10):
        ....:     g = graphs.RandomTriangulation(30,embed=True)
        ....:     assert g.is_planar() and g.size() == 3*g.order()-6
    """
    from sage.misc.prandom import normalvariate
    from sage.geometry.polyhedron.constructor import Polyhedron
    from sage.rings.real_double import RDF

    # this function creates a random unit vector in R^3
    def rand_unit_vec():
        vec = [normalvariate(0, 1) for k in range(3)]
        mag = sum([x * x for x in vec]) ** 0.5
        return [x / mag for x in vec]

    # generate n unit vectors at random
    points = [rand_unit_vec() for k in range(n)]

    # find their convex hull
    P = Polyhedron(vertices=points, base_ring=base_ring)

    # extract the 1-skeleton
    g = P.vertex_graph()
    g.rename('Planar triangulation on {} vertices'.format(n))

    if embed:
        from sage.geometry.polyhedron.plot import ProjectionFuncStereographic
        from sage.modules.free_module_element import vector
        proj = ProjectionFuncStereographic([0, 0, 1])
        ppoints = [proj(vector(x)) for x in points]
        g.set_pos({i: ppoints[i] for i in range(len(points))})

    return g
Пример #37
0
    def induced_out_partition(self, trans, ieq):
        r"""
        Returns the output partition obtained as the induction of the given
        transformation on the domain given by an inequality.

        Note: the output partition corresponds to the arrival partition in
        the domain, not the initial one.

        INPUT:

        - ``trans`` -- a function: polyhedron -> polyhedron
        - ``ieq`` -- list, an inequality. An entry equal to "[-1,7,3,4]"
          represents the inequality 7x_1+3x_2+4x_3>= 1.

        OUTPUT:

            dict of polyhedron partitions with keys giving the return time

        EXAMPLES::

            sage: from slabbe import PolyhedronPartition, rotation_mod
            sage: h = 1/3
            sage: p = Polyhedron([(0,h),(0,1),(h,1)])
            sage: q = Polyhedron([(0,0), (0,h), (h,1), (h,0)])
            sage: r = Polyhedron([(h,1), (1,1), (1,h), (h,0)])
            sage: s = Polyhedron([(h,0), (1,0), (1,h)])
            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: u = rotation_mod(0, 1/3, 1, QQ)
            sage: ieq = [h, -1, 0]   # x0 <= h
            sage: P.induced_out_partition(u, ieq)
            {3: Polyhedron partition of 4 atoms with 4 letters}

        ::

            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: ieq2 = [1/2, -1, 0]   # x0 <= 1/2
            sage: d = P.induced_out_partition(u, ieq2)
            sage: d
            {1: Polyhedron partition of 2 atoms with 2 letters,
             2: Polyhedron partition of 3 atoms with 3 letters,
             3: Polyhedron partition of 4 atoms with 4 letters}
            sage: Q = PolyhedronPartition(d[1].atoms()+d[2].atoms()+d[3].atoms())
            sage: Q.is_pairwise_disjoint()
            True

        ::

            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: ieq3 = [-1/2, 1, 0]   # x0 >= 1/2
            sage: P.induced_out_partition(u, ieq3)
            {2: Polyhedron partition of 3 atoms with 3 letters,
             3: Polyhedron partition of 4 atoms with 4 letters}

        It is an error if the induced region is empty::

            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: ieq4 = [-1/2, -1, 0]   # x0 <= -1/2
            sage: P.induced_out_partition(u, ieq4)
            Traceback (most recent call last):
            ...
            ValueError: Inequality An inequality (-2, 0) x - 1 >= 0 does
            not intersect P (=Polyhedron partition of 4 atoms with 4
            letters)

        The whole domain::

            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
            sage: ieq5 = [1/2, 1, 0]   # x0 >= -1/2
            sage: P.induced_out_partition(u, ieq5)
            {1: Polyhedron partition of 4 atoms with 4 letters}

        An irrational rotation::

            sage: z = polygen(QQ, 'z') #z = QQ['z'].0 # same as
            sage: K = NumberField(z**2-z-1, 'phi', embedding=RR(1.6))
            sage: phi = K.gen()
            sage: h = 1/phi^2
            sage: p = Polyhedron([(0,h),(0,1),(h,1)])
            sage: q = Polyhedron([(0,0), (0,h), (h,1), (h,0)])
            sage: r = Polyhedron([(h,1), (1,1), (1,h), (h,0)])
            sage: s = Polyhedron([(h,0), (1,0), (1,h)])
            sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s}, base_ring=K)
            sage: u = rotation_mod(0, 1/phi, 1, K)
            sage: ieq = [phi^-4, -1, 0]   # x0 <= phi^-4
            sage: d = P.induced_out_partition(u, ieq)
            sage: d
            {5: Polyhedron partition of 6 atoms with 6 letters,
             8: Polyhedron partition of 9 atoms with 9 letters}
        """
        # good side of the hyperplane
        half = Polyhedron(ieqs=[ieq])
        half_part = PolyhedronPartition([half])
        # the other side of the hyperplane
        other_half = Polyhedron(ieqs=[[-a for a in ieq]])
        other_half_part = PolyhedronPartition([other_half])
        # initial refinement
        P = self.refinement(half_part)
        if len(P) == 0:
            raise ValueError("Inequality {} does not intersect P "
                    "(={})".format(half.inequalities()[0], self))
        level = 1
        ans = {}
        P = P.apply_transformation(trans)
        while len(P):
            P_returned = P.refinement(half_part)
            if P_returned:
                ans[level] = P_returned
            # for what is remaining we do:
            P = P.refinement(other_half_part)
            P = P.refinement(self)
            P = P.apply_transformation(trans)
            level += 1
        return ans