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
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
Пример #3
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)
Пример #4
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)
Пример #5
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: print 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, field=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,
                                     field=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
Пример #6
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