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
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 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)
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
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