Пример #1
0
    def Torus(r=2, R=3, name="Torus"):
        r"""
        Returns a torus obtained by revolving a circle of radius ``r`` around
        a coplanar axis ``R`` units away from the center of the circle. The
        parametrization used is

        .. MATH::

            \begin{aligned}
              x(u, v) & = (R + r \cos(v)) \cos(u); \\
              y(u, v) & = (R + r \cos(v)) \sin(u); \\
              z(u, v) & = r \sin(v).
            \end{aligned}

        INPUT:

        - ``r``, ``R`` -- Minor and major radius of the torus.

        - ``name`` -- string. Name of the surface.

        EXAMPLES::

            sage: torus = surfaces.Torus(); torus
            Parametrized surface ('Torus') with equation ((2*cos(v) + 3)*cos(u), (2*cos(v) + 3)*sin(u), 2*sin(v))
            sage: torus.plot()
            Graphics3d Object

        """

        u, v = var("u, v")
        torus_eq = [(R + r * cos(v)) * cos(u), (R + r * cos(v)) * sin(u), r * sin(v)]
        coords = ((u, 0, 2 * pi), (v, 0, 2 * pi))

        return ParametrizedSurface3D(torus_eq, coords, name)
Пример #2
0
    def Klein(r=1, name="Klein bottle"):
        r"""
        Returns the Klein bottle, in the figure-8 parametrization given by

        .. MATH::

            \begin{aligned}
              x(u, v) & = (r + \cos(u/2)\cos(v) - \sin(u/2)\sin(2v)) \cos(u); \\
              y(u, v) & = (r + \cos(u/2)\cos(v) - \sin(u/2)\sin(2v)) \sin(u); \\
              z(u, v) & = \sin(u/2)\cos(v) + \cos(u/2)\sin(2v).
            \end{aligned}

        INPUT:

        - ``r`` -- radius of the "figure-8" circle.

        - ``name`` -- string. Name of the surface.

        EXAMPLES::

            sage: klein = surfaces.Klein(); klein
            Parametrized surface ('Klein bottle') with equation (-(sin(1/2*u)*sin(2*v) - cos(1/2*u)*sin(v) - 1)*cos(u), -(sin(1/2*u)*sin(2*v) - cos(1/2*u)*sin(v) - 1)*sin(u), cos(1/2*u)*sin(2*v) + sin(1/2*u)*sin(v))
            sage: klein.plot()
            Graphics3d Object

        """

        u, v = var("u, v")
        x = (r + cos(u / 2) * sin(v) - sin(u / 2) * sin(2 * v)) * cos(u)
        y = (r + cos(u / 2) * sin(v) - sin(u / 2) * sin(2 * v)) * sin(u)
        z = sin(u / 2) * sin(v) + cos(u / 2) * sin(2 * v)
        klein_eq = [x, y, z]
        coords = ((u, 0, 2 * pi), (v, 0, 2 * pi))

        return ParametrizedSurface3D(klein_eq, coords, name)
Пример #3
0
    def Crosscap(r=1, name="Crosscap"):
        r"""
        Returns a crosscap surface, with parametrization

        .. MATH::

            \begin{aligned}
              x(u, v) & = r(1 + \cos(v)) \cos(u); \\
              y(u, v) & = r(1 + \cos(v)) \sin(u); \\
              z(u, v) & = - r\tanh(u - \pi) \sin(v).
            \end{aligned}

        INPUT:

        - ``r`` -- surface parameter.

        - ``name`` -- string. Name of the surface.

        EXAMPLES::

            sage: crosscap = surfaces.Crosscap(); crosscap
            Parametrized surface ('Crosscap') with equation ((cos(v) + 1)*cos(u), (cos(v) + 1)*sin(u), -sin(v)*tanh(-pi + u))
            sage: crosscap.plot()

        """

        u, v = var('u, v')
        crosscap_eq = [r*(1+cos(v))*cos(u), r*(1+cos(v))*sin(u),
                       -tanh(u-pi)*r*sin(v)]
        coords = ((u, 0, 2*pi), (v, 0, 2*pi))

        return ParametrizedSurface3D(crosscap_eq, coords, name)
Пример #4
0
    def Dini(a=1, b=1, name="Dini's surface"):
        r"""
        Returns Dini's surface, with parametrization

        .. MATH::

            \begin{aligned}
              x(u, v) & = a \cos(u)\sin(v); \\
              y(u, v) & = a \sin(u)\sin(v); \\
              z(u, v) & = u + \log(\tan(v/2)) + \cos(v).
            \end{aligned}

        INPUT:

        - ``a, b`` -- surface parameters.

        - ``name`` -- string. Name of the surface.

        EXAMPLES::

            sage: dini = surfaces.Dini(a=3, b=4); dini
            Parametrized surface ('Dini's surface') with equation (3*cos(u)*sin(v), 3*sin(u)*sin(v), 4*u + 3*cos(v) + 3*log(tan(1/2*v)))
            sage: dini.plot()  # not tested -- known bug (see #10132)

        """

        u, v = var("u, v")
        dini_eq = [a * cos(u) * sin(v), a * sin(u) * sin(v), a * (cos(v) + log(tan(v / 2))) + b * u]
        coords = ((u, 0, 2 * pi), (v, 0, 2 * pi))

        return ParametrizedSurface3D(dini_eq, coords, name)
Пример #5
0
    def Crosscap(r=1, name="Crosscap"):
        r"""
        Return a crosscap surface, with parametrization

        .. MATH::

            \begin{aligned}
              x(u, v) & = r(1 + \cos(v)) \cos(u); \\
              y(u, v) & = r(1 + \cos(v)) \sin(u); \\
              z(u, v) & = - r\tanh(u - \pi) \sin(v).
            \end{aligned}

        INPUT:

        - ``r`` -- surface parameter.

        - ``name`` -- string. Name of the surface.

        For more information, see :wikipedia:`Cross-cap`.

        EXAMPLES::

            sage: crosscap = surfaces.Crosscap(); crosscap
            Parametrized surface ('Crosscap') with equation ((cos(v) + 1)*cos(u), (cos(v) + 1)*sin(u), -sin(v)*tanh(-pi + u))
            sage: crosscap.plot()
            Graphics3d Object
        """
        u, v = var('u, v')
        crosscap_eq = [
            r * (1 + cos(v)) * cos(u), r * (1 + cos(v)) * sin(u),
            -tanh(u - pi) * r * sin(v)
        ]
        coords = ((u, 0, 2 * pi), (v, 0, 2 * pi))
        return ParametrizedSurface3D(crosscap_eq, coords, name)
Пример #6
0
    def Dini(a=1, b=1, name="Dini's surface"):
        r"""
        Return Dini's surface, with parametrization

        .. MATH::

            \begin{aligned}
              x(u, v) & = a \cos(u)\sin(v); \\
              y(u, v) & = a \sin(u)\sin(v); \\
              z(u, v) & = u + \log(\tan(v/2)) + \cos(v).
            \end{aligned}

        INPUT:

        - ``a, b`` -- surface parameters.

        - ``name`` -- string. Name of the surface.

        For more information, see :wikipedia:`Dini%27s_surface`.

        EXAMPLES::

            sage: dini = surfaces.Dini(a=3, b=4); dini
            Parametrized surface ('Dini's surface') with equation (3*cos(u)*sin(v), 3*sin(u)*sin(v), 4*u + 3*cos(v) + 3*log(tan(1/2*v)))
            sage: dini.plot()
            Graphics3d Object
        """
        u, v = var('u, v')
        dini_eq = [
            a * cos(u) * sin(v), a * sin(u) * sin(v),
            a * (cos(v) + log(tan(v / 2))) + b * u
        ]
        coords = ((u, 0, 2 * pi), (v, 0, 2 * pi))
        return ParametrizedSurface3D(dini_eq, coords, name)
Пример #7
0
    def evaluate_L(self, affine_parameter, solution_key=None):
        r"""
        Compute the conserved angular momentum about the rotation axis `L` at
        a given value of the affine parameter `\lambda`.

        INPUT:

        - ``affine_parameter`` -- value of the affine parameter `\lambda`
        - ``solution_key`` -- (default: ``None``) string denoting the numerical
          solution to use for the evaluation; if ``None``, the latest solution
          computed by :meth:`integrate` is used.

        OUTPUT:

        - value of `L`

        """
        p = self.evaluate_tangent_vector(affine_parameter,
                                         solution_key=solution_key)
        point = p.parent().base_point()
        BLchart = self._spacetime.boyer_lindquist_coordinates()
        r, th = BLchart(point)[1:3]
        a, m = self._a, self._m
        r2 = r**2
        a2 = a**2
        rho2 = r2 + (a * cos(th))**2
        p_comp = p.components(basis=BLchart.frame().at(point))
        pt = p_comp[0]
        pph = p_comp[3]
        bs = 2 * a * m * r * sin(th)**2 / rho2
        L = -bs * pt + (r2 + a2 + a * bs) * sin(th)**2 * pph
        return L.substitute(self._numerical_substitutions())
Пример #8
0
    def Torus(r=2, R=3, name="Torus"):
        r"""
        Return a torus obtained by revolving a circle of radius ``r`` around
        a coplanar axis ``R`` units away from the center of the circle. The
        parametrization used is

        .. MATH::

            \begin{aligned}
              x(u, v) & = (R + r \cos(v)) \cos(u); \\
              y(u, v) & = (R + r \cos(v)) \sin(u); \\
              z(u, v) & = r \sin(v).
            \end{aligned}

        INPUT:

        - ``r``, ``R`` -- Minor and major radius of the torus.

        - ``name`` -- string. Name of the surface.

        For more information, see :wikipedia:`Torus`.

        EXAMPLES::

            sage: torus = surfaces.Torus(); torus
            Parametrized surface ('Torus') with equation ((2*cos(v) + 3)*cos(u), (2*cos(v) + 3)*sin(u), 2*sin(v))
            sage: torus.plot()
            Graphics3d Object
        """
        u, v = var('u, v')
        torus_eq = [(R + r * cos(v)) * cos(u), (R + r * cos(v)) * sin(u),
                    r * sin(v)]
        coords = ((u, 0, 2 * pi), (v, 0, 2 * pi))
        return ParametrizedSurface3D(torus_eq, coords, name)
Пример #9
0
    def Dini(a=1, b=1, name="Dini's surface"):
        r"""
        Returns Dini's surface, with parametrization

        .. MATH::

            \begin{aligned}
              x(u, v) & = a \cos(u)\sin(v); \\
              y(u, v) & = a \sin(u)\sin(v); \\
              z(u, v) & = u + \log(\tan(v/2)) + \cos(v).
            \end{aligned}

        INPUT:

        - ``a, b`` -- surface parameters.

        - ``name`` -- string. Name of the surface.

        EXAMPLES::

            sage: dini = surfaces.Dini(a=3, b=4); dini
            Parametrized surface ('Dini's surface') with equation (3*cos(u)*sin(v), 3*sin(u)*sin(v), 4*u + 3*cos(v) + 3*log(tan(1/2*v)))
            sage: dini.plot()  # not tested -- known bug (see #10132)

        """

        u, v = var('u, v')
        dini_eq = [a*cos(u)*sin(v), a*sin(u)*sin(v),
                   a*(cos(v) + log(tan(v/2))) + b*u]
        coords = ((u, 0, 2*pi), (v, 0, 2*pi))


        return ParametrizedSurface3D(dini_eq, coords, name)
Пример #10
0
    def Klein(r=1, name="Klein bottle"):
        r"""
        Return the Klein bottle, in the figure-8 parametrization given by

        .. MATH::

            \begin{aligned}
              x(u, v) & = (r + \cos(u/2)\cos(v) - \sin(u/2)\sin(2v)) \cos(u); \\
              y(u, v) & = (r + \cos(u/2)\cos(v) - \sin(u/2)\sin(2v)) \sin(u); \\
              z(u, v) & = \sin(u/2)\cos(v) + \cos(u/2)\sin(2v).
            \end{aligned}

        INPUT:

        - ``r`` -- radius of the "figure-8" circle.

        - ``name`` -- string. Name of the surface.

        For more information, see :wikipedia:`Klein_bottle`.

        EXAMPLES::

            sage: klein = surfaces.Klein(); klein
            Parametrized surface ('Klein bottle') with equation (-(sin(1/2*u)*sin(2*v) - cos(1/2*u)*sin(v) - 1)*cos(u), -(sin(1/2*u)*sin(2*v) - cos(1/2*u)*sin(v) - 1)*sin(u), cos(1/2*u)*sin(2*v) + sin(1/2*u)*sin(v))
            sage: klein.plot()
            Graphics3d Object
        """
        u, v = var('u, v')
        x = (r + cos(u / 2) * sin(v) - sin(u / 2) * sin(2 * v)) * cos(u)
        y = (r + cos(u / 2) * sin(v) - sin(u / 2) * sin(2 * v)) * sin(u)
        z = sin(u / 2) * sin(v) + cos(u / 2) * sin(2 * v)
        klein_eq = [x, y, z]
        coords = ((u, 0, 2 * pi), (v, 0, 2 * pi))

        return ParametrizedSurface3D(klein_eq, coords, name)
Пример #11
0
        def plot_arc(radius, p, q, **opts):
            # TODO: THIS SHOULD USE THE EXISTING PLOT OF ARCS!
            # plot the arc from p to q differently depending on the type of self
            p = ZZ(p)
            q = ZZ(q)
            t = var('t')
            if p - q in [1, -1]:

                def f(t):
                    return (radius * cos(t), radius * sin(t))

                (p, q) = sorted([p, q])
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                return parametric_plot(f(t), (t, angle_q, angle_p), **opts)
            if self.type() == 'A':
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                if angle_p < angle_q:
                    angle_p += 2 * pi
                internal_angle = angle_p - angle_q
                if internal_angle > pi:
                    (angle_p, angle_q) = (angle_q + 2 * pi, angle_p)
                    internal_angle = angle_p - angle_q
                angle_center = (angle_p + angle_q) / 2
                hypotenuse = radius / cos(internal_angle / 2)
                radius_arc = hypotenuse * sin(internal_angle / 2)
                center = (hypotenuse * cos(angle_center),
                          hypotenuse * sin(angle_center))
                center_angle_p = angle_p + pi / 2
                center_angle_q = angle_q + 3 * pi / 2

                def f(t):
                    return (radius_arc * cos(t) + center[0],
                            radius_arc * sin(t) + center[1])

                return parametric_plot(f(t),
                                       (t, center_angle_p, center_angle_q),
                                       **opts)
            elif self.type() == 'D':
                if p >= q:
                    q += self.r()
                px = -2 * pi * p / self.r() + pi / 2
                qx = -2 * pi * q / self.r() + pi / 2
                arc_radius = (px - qx) / 2
                arc_center = qx + arc_radius

                def f(t):
                    return exp(I * ((cos(t) + I * sin(t)) * arc_radius +
                                    arc_center)) * radius

                return parametric_plot((real_part(f(t)), imag_part(f(t))),
                                       (t, 0, pi), **opts)
Пример #12
0
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES::

            sage: HyperbolicPlane().PD().get_geodesic(0, 1).show()
            Graphics object consisting of 2 graphics primitives
        """
        opts = dict([('axes', False), ('aspect_ratio', 1)])
        opts.update(self.graphics_options())
        opts.update(options)
        end_1, end_2 = [CC(k.coordinates()) for k in self.endpoints()]
        bd_1, bd_2 = [CC(k.coordinates()) for k in self.ideal_endpoints()]
        # Check to see if it's a line
        if bool(real(bd_1)*imag(bd_2) - real(bd_2)*imag(bd_1))**2 < EPSILON:
            from sage.plot.line import line
            pic = line([(real(bd_1),imag(bd_1)),(real(bd_2),imag(bd_2))],
                       **opts)
        else:
            # If we are here, we know it's not a line
            # So we compute the center and radius of the circle
            center = (1/(real(bd_1)*imag(bd_2) - real(bd_2)*imag(bd_1)) *
                ((imag(bd_2)-imag(bd_1)) + (real(bd_1)-real(bd_2))*I))
            radius = RR(abs(bd_1 - center)) # abs is Euclidean distance
            # Now we calculate the angles for the parametric plot
            theta1 = CC(end_1 - center).arg()
            theta2 = CC(end_2 - center).arg()
            if theta2 < theta1:
                theta1, theta2 = theta2, theta1
            from sage.calculus.var import var
            from sage.plot.plot import parametric_plot
            x = var('x')
            mid = (theta1 + theta2)/2.0
            if (radius*cos(mid) + real(center))**2 + \
               (radius*sin(mid) + imag(center))**2 > 1.0:
                # Swap theta1 and theta2
                tmp = theta1 + 2*pi
                theta1 = theta2
                theta2 = tmp
                pic = parametric_plot((radius*cos(x) + real(center),
                                       radius*sin(x) + imag(center)),
                                      (x, theta1, theta2), **opts)

            else:
                pic = parametric_plot((radius*cos(x) + real(center),
                                   radius*sin(x) + imag(center)),
                                  (x, theta1, theta2), **opts)
        if boundary:
            bd_pic = self._model.get_background_graphic()
            pic = bd_pic + pic
        return pic
Пример #13
0
    def transform(self, radius=None, azimuth=None, elevation=None):
        """
        A spherical elevation coordinates transform.

        EXAMPLES::

            sage: T = SphericalElevation('radius', ['azimuth', 'elevation'])
            sage: T.transform(radius=var('r'), azimuth=var('theta'), elevation=var('phi'))
            (r*cos(phi)*cos(theta), r*cos(phi)*sin(theta), r*sin(phi))
        """
        return (radius * cos(elevation) * cos(azimuth),
                radius * cos(elevation) * sin(azimuth),
                radius * sin(elevation))
Пример #14
0
    def transform(self, radius=None, azimuth=None, elevation=None):
        """
        A spherical elevation coordinates transform.

        EXAMPLE::

            sage: T = SphericalElevation('radius', ['azimuth', 'elevation'])
            sage: T.transform(radius=var('r'), azimuth=var('theta'), elevation=var('phi'))
            (r*cos(phi)*cos(theta), r*cos(phi)*sin(theta), r*sin(phi))
        """
        return (radius * cos(elevation) * cos(azimuth),
                radius * cos(elevation) * sin(azimuth),
                radius * sin(elevation))
Пример #15
0
def Torus(R=2, r=1, names=None):
    """
    Generate a 2-dimensional torus embedded in Euclidean space.

    The shortcut operator ``.<,>`` can be used to specify the coordinates.

    INPUT:

    - ``R`` -- (default: ``2``) distance form the center to the
      center of the tube
    - ``r`` -- (default: ``1``) radius of the tube
    - ``names`` -- (default: ``None``) name of the coordinates,
      automatically set by the shortcut operator

    OUTPUT:

    - Riemannian manifold

    EXAMPLES::

        sage: T.<theta, phi> = manifolds.Torus(3, 1)
        sage: T
        2-dimensional Riemannian submanifold T embedded in the Euclidean
         space E^3
        sage: T.atlas()
        [Chart (T, (theta, phi))]
        sage: T.embedding().display()
        T → E^3
           (theta, phi) ↦ (X, Y, Z) = ((cos(theta) + 3)*cos(phi),
                                          (cos(theta) + 3)*sin(phi),
                                          sin(theta))
        sage: T.metric().display()
        gamma = dtheta⊗dtheta + (cos(theta)^2 + 6*cos(theta) + 9) dphi⊗dphi
    """
    from sage.functions.trig import cos, sin
    from sage.manifolds.manifold import Manifold
    from sage.manifolds.differentiable.examples.euclidean import EuclideanSpace
    E = EuclideanSpace(3, symbols='X Y Z')
    M = Manifold(2, 'T', ambient=E, structure="Riemannian")
    if names is None:
        names = ("th", "ph")
    names = tuple([names[i] + ":(-pi,pi):periodic" for i in range(2)])
    C = M.chart(names=names)
    M._first_ngens = C._first_ngens
    th, ph = C[:]
    coordfunc = [(R + r * cos(th)) * cos(ph), (R + r * cos(th)) * sin(ph),
                 r * sin(th)]
    imm = M.diff_map(E, coordfunc)
    M.set_embedding(imm)
    M.induced_metric()
    return M
Пример #16
0
    def metric(self):
        r"""
        Return the metric tensor.

        EXAMPLES::

            sage: from kerrgeodesic_gw import KerrBH
            sage: a, m = var('a m')
            sage: BH = KerrBH(a, m)
            sage: BH.metric()
            Lorentzian metric g on the Kerr spacetime M
            sage: BH.metric().display()
            g = -(a^2*cos(th)^2 - 2*m*r + r^2)/(a^2*cos(th)^2 + r^2) dt*dt
             - 2*a*m*r*sin(th)^2/(a^2*cos(th)^2 + r^2) dt*dph
             + (a^2*cos(th)^2 + r^2)/(a^2 - 2*m*r + r^2) dr*dr
             + (a^2*cos(th)^2 + r^2) dth*dth
             - 2*a*m*r*sin(th)^2/(a^2*cos(th)^2 + r^2) dph*dt
             + (2*a^2*m*r*sin(th)^4 + (a^2*r^2 + r^4 + (a^4 + a^2*r^2)*cos(th)^2)*sin(th)^2)/(a^2*cos(th)^2 + r^2) dph*dph

        The Schwarzschild metric::

            sage: KerrBH(0, m).metric().display()
            g = (2*m - r)/r dt*dt - r/(2*m - r) dr*dr + r^2 dth*dth
             + r^2*sin(th)^2 dph*dph

        """
        if self._metric is None:
            # Initialization of the metric tensor in Boyer-Lindquist coordinates
            cBL = self.boyer_lindquist_coordinates()
            t, r, th, ph = cBL[:]
            g = super(KerrBH, self).metric()  # the initialized metric object
            m = self._m
            a = self._a
            r2 = r**2
            a2 = a**2
            rho2 = r2 + (a * cos(th))**2
            Delta = r2 - 2 * m * r + a2
            fBL = cBL.frame()  # vector frame associated to BL coordinates
            g[fBL, 0, 0, cBL] = -1 + 2 * m * r / rho2
            g[fBL, 0, 3, cBL] = -2 * a * m * r * sin(th)**2 / rho2
            g[fBL, 1, 1, cBL] = rho2 / Delta
            g[fBL, 2, 2, cBL] = rho2
            g[fBL, 3, 3, cBL] = (r2 + a2 + 2 * m * r *
                                 (a * sin(th))**2 / rho2) * sin(th)**2
            for i in self.irange():
                g[fBL, i, i, cBL].simplify()
            g[fBL, 0, 3, cBL].simplify()
        return self._metric
    def plot(self, **kwargs):
        """
        Return a graphics object representing the Kontsevich graph.

        INPUT:

        - ``edge_labels`` (boolean, default True) -- if True, show edge labels.
        - ``indices`` (boolean, default False) -- if True, show indices as
          edge labels instead of L and R; see :meth:`._latex_`.
        - ``upright`` (boolean, default False) -- if True, try to plot the
          graph with the ground vertices on the bottom and the rest on top.
        """
        if not 'edge_labels' in kwargs:
            kwargs['edge_labels'] = True  # show edge labels by default
        if 'indices' in kwargs:
            del kwargs['indices']
            KG = DiGraph(self)
            for (k, e) in enumerate(self.edges()):
                KG.delete_edge(e)
                KG.add_edge((e[0], e[1], chr(97 + k)))
            return KG.plot(**kwargs)
        if len(self.ground_vertices()) == 2 and 'upright' in kwargs:
            del kwargs['upright']
            kwargs['save_pos'] = True
            DiGraph.plot(self, **kwargs)
            positions = self.get_pos()
            # translate F to origin:
            F_pos = vector(positions[self.ground_vertices()[0]])
            for p in positions:
                positions[p] = list(vector(positions[p]) - F_pos)
            # scale F - G distance to 1:
            G_len = abs(vector(positions[self.ground_vertices()[1]]))
            for p in positions:
                positions[p] = list(vector(positions[p]) / G_len)
            # rotate the vector F - G to (1,0)
            from math import atan2
            theta = -atan2(positions[self.ground_vertices()[1]][1],
                           positions[self.ground_vertices()[1]][0])
            for p in positions:
                positions[p] = list(
                    matrix([[cos(theta), -(sin(theta))],
                            [sin(theta), cos(theta)]]) * vector(positions[p]))
            # flip if most things are below the x-axis:
            if len([(x, y) for (x, y) in positions.values() if y < 0]) / len(
                    self.internal_vertices()) > 0.5:
                for p in positions:
                    positions[p] = [positions[p][0], -positions[p][1]]
        return DiGraph.plot(self, **kwargs)
Пример #18
0
        def plot_arc(radius, p, q, **opts):
            # TODO: THIS SHOULD USE THE EXISTING PLOT OF ARCS!
            # plot the arc from p to q differently depending on the type of self
            p = ZZ(p)
            q = ZZ(q)
            t = var('t')
            if p - q in [1, -1]:
                def f(t):
                    return (radius * cos(t), radius * sin(t))
                (p, q) = sorted([p, q])
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                return parametric_plot(f(t), (t, angle_q, angle_p), **opts)
            if self.type() == 'A':
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                if angle_p < angle_q:
                    angle_p += 2 * pi
                internal_angle = angle_p - angle_q
                if internal_angle > pi:
                    (angle_p, angle_q) = (angle_q + 2 * pi, angle_p)
                    internal_angle = angle_p - angle_q
                angle_center = (angle_p+angle_q) / 2
                hypotenuse = radius / cos(internal_angle / 2)
                radius_arc = hypotenuse * sin(internal_angle / 2)
                center = (hypotenuse * cos(angle_center),
                          hypotenuse * sin(angle_center))
                center_angle_p = angle_p + pi / 2
                center_angle_q = angle_q + 3 * pi / 2

                def f(t):
                    return (radius_arc * cos(t) + center[0],
                            radius_arc * sin(t) + center[1])
                return parametric_plot(f(t), (t, center_angle_p,
                                              center_angle_q), **opts)
            elif self.type() == 'D':
                if p >= q:
                    q += self.r()
                px = -2 * pi * p / self.r() + pi / 2
                qx = -2 * pi * q / self.r() + pi / 2
                arc_radius = (px - qx) / 2
                arc_center = qx + arc_radius

                def f(t):
                    return exp(I * ((cos(t) + I * sin(t)) *
                                    arc_radius + arc_center)) * radius
                return parametric_plot((real_part(f(t)), imag_part(f(t))),
                                       (t, 0, pi), **opts)
Пример #19
0
    def Catenoid(c=1, name="Catenoid"):
        r"""
        Returns a catenoid surface, with parametric representation

        .. MATH::

            \begin{aligned}
              x(u, v) & = c \cosh(v/c) \cos(u); \\
              y(u, v) & = c \cosh(v/c) \sin(u); \\
              z(u, v) & = v.
            \end{aligned}

        INPUT:

        - ``c`` -- surface parameter.

        - ``name`` -- string. Name of the surface.


        EXAMPLES::

            sage: cat = surfaces.Catenoid(); cat
            Parametrized surface ('Catenoid') with equation (cos(u)*cosh(v), cosh(v)*sin(u), v)
            sage: cat.plot()
            Graphics3d Object

        """
        u, v = var("u, v")
        catenoid_eq = [c * cosh(v / c) * cos(u), c * cosh(v / c) * sin(u), v]
        coords = ((u, 0, 2 * pi), (v, -1, 1))

        return ParametrizedSurface3D(catenoid_eq, coords, name)
    def _i_rotation(self, z, alpha):
        r"""
        Return the resulting point after applying a hyperbolic
        rotation centered at `0 + i` and angle ``alpha`` to ``z``.

        INPUT:

        - ``z``-- point in the upper complex halfplane to which
          apply the isometry

        - ``alpha``-- angle of rotation (radians,counterwise)

        OUTPUT:

        - rotated point in the upper complex halfplane

        TESTS::

            sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
            sage: P = HyperbolicRegularPolygon(4, pi/4, 1+I, {})
            sage: P._i_rotation(2+I, pi/2)
            I - 2
        """
        _a = alpha / 2
        _c = cos(_a)
        _s = sin(_a)
        G = matrix([[_c, _s], [-_s, _c]])
        return (G[0][0] * z + G[0][1]) / (G[1][0] * z + G[1][1])
Пример #21
0
    def _eval_(self, a, z):
        """
        EXAMPLES::

            sage: struve_H(0,0)
            0
            sage: struve_H(pi,0)
            0
            sage: struve_H(-1/2,x)
            sqrt(2)*sqrt(1/(pi*x))*sin(x)
            sage: struve_H(1/2,-1)
            -sqrt(2)*sqrt(-1/pi)*(cos(1) - 1)
            sage: struve_H(1/2,pi)
            2*sqrt(2)/pi
            sage: struve_H(2,x)
            struve_H(2, x)
            sage: struve_H(-3/2,x)
            -bessel_J(3/2, x)
        """
        from sage.symbolic.ring import SR
        if z.is_zero() \
                and (SR(a).is_numeric() or SR(a).is_constant()) \
                and a.real() >= -1:
                return ZZ(0)
        if a == -Integer(1)/2:
            from sage.functions.trig import sin
            return sqrt(2/(pi*z)) * sin(z)
        if a == Integer(1)/2:
            from sage.functions.trig import cos
            return sqrt(2/(pi*z)) * (1-cos(z))
        if a < 0 and not SR(a).is_integer() and SR(2*a).is_integer():
            from sage.rings.rational_field import QQ
            n = (a*(-2) - 1)/2
            return Integer(-1)**n * bessel_J(n+QQ(1)/2, z)
Пример #22
0
    def Helicoid(h=1, name="Helicoid"):
        r"""
        Return a helicoid surface, with parametrization

        .. MATH::

            \begin{aligned}
              x(\rho, \theta) & = \rho \cos(\theta); \\
              y(\rho, \theta) & = \rho \sin(\theta); \\
              z(\rho, \theta) & = h\theta/(2\pi).
            \end{aligned}

        INPUT:

        - ``h`` -- distance along the z-axis between two
          successive turns of the helicoid.

        - ``name`` -- string. Name of the surface.

        For more information, see :wikipedia:`Helicoid`.

        EXAMPLES::

            sage: helicoid = surfaces.Helicoid(h=2); helicoid
            Parametrized surface ('Helicoid') with equation (rho*cos(theta), rho*sin(theta), theta/pi)
            sage: helicoid.plot()
            Graphics3d Object
        """
        rho, theta = var('rho, theta')
        helicoid_eq = [
            rho * cos(theta), rho * sin(theta), h * theta / (2 * pi)
        ]
        coords = ((rho, -2, 2), (theta, 0, 2 * pi))
        return ParametrizedSurface3D(helicoid_eq, coords, name)
Пример #23
0
    def evaluate_E(self, affine_parameter, solution_key=None):
        r"""
        Compute the conserved energy `E` at a given value of the affine
        parameter `\lambda`.

        INPUT:

        - ``affine_parameter`` -- value of the affine parameter `\lambda`
        - ``solution_key`` -- (default: ``None``) string denoting the numerical
          solution to use for the evaluation; if ``None``, the latest solution
          computed by :meth:`integrate` is used.

        OUTPUT:

        - value of `E`

        """
        p = self.evaluate_tangent_vector(affine_parameter,
                                         solution_key=solution_key)
        point = p.parent().base_point()
        BLchart = self._spacetime.boyer_lindquist_coordinates()
        r, th = BLchart(point)[1:3]
        a, m = self._a, self._m
        rho2 = r**2 + (a * cos(th))**2
        p_comp = p.components(basis=BLchart.frame().at(point))
        pt = p_comp[0]
        pph = p_comp[3]
        b = 2 * m * r / rho2
        E = (1 - b) * pt + b * a * sin(th)**2 * pph
        return E.substitute(self._numerical_substitutions())
Пример #24
0
    def Catenoid(c=1, name="Catenoid"):
        r"""
        Return a catenoid surface, with parametric representation

        .. MATH::

            \begin{aligned}
              x(u, v) & = c \cosh(v/c) \cos(u); \\
              y(u, v) & = c \cosh(v/c) \sin(u); \\
              z(u, v) & = v.
            \end{aligned}

        INPUT:

        - ``c`` -- surface parameter.

        - ``name`` -- string. Name of the surface.

        For more information, see :wikipedia:`Catenoid`.

        EXAMPLES::

            sage: cat = surfaces.Catenoid(); cat
            Parametrized surface ('Catenoid') with equation (cos(u)*cosh(v), cosh(v)*sin(u), v)
            sage: cat.plot()
            Graphics3d Object
        """
        u, v = var('u, v')
        catenoid_eq = [c * cosh(v / c) * cos(u), c * cosh(v / c) * sin(u), v]
        coords = ((u, 0, 2 * pi), (v, -1, 1))
        return ParametrizedSurface3D(catenoid_eq, coords, name)
Пример #25
0
    def evaluate_Q(self, affine_parameter, solution_key=None):
        r"""
        Compute the Carter constant `Q` at a given value of the affine
        parameter `\lambda`.

        INPUT:

        - ``affine_parameter`` -- value of the affine parameter `\lambda`
        - ``solution_key`` -- (default: ``None``) string denoting the numerical
          solution to use for the evaluation; if ``None``, the latest solution
          computed by :meth:`integrate` is used.

        OUTPUT:

        - value of `Q`

        """
        p = self.evaluate_tangent_vector(affine_parameter,
                                         solution_key=solution_key)
        point = p.parent().base_point()
        BLchart = self._spacetime.boyer_lindquist_coordinates()
        r, th = BLchart(point)[1:3]
        a = self._a
        rho4 = (r**2 + (a * cos(th))**2)**2
        mu2 = self.evaluate_mu(affine_parameter)**2
        E2 = self.evaluate_E(affine_parameter, solution_key=solution_key)**2
        L2 = self.evaluate_L(affine_parameter, solution_key=solution_key)**2
        p_comp = p.components(basis=BLchart.frame().at(point))
        pth = p_comp[2]
        Q = rho4 * pth**2 + cos(th)**2 * (L2 / sin(th)**2 + a**2 * (mu2 - E2))
        return Q.substitute(self._numerical_substitutions())
Пример #26
0
    def Helicoid(h=1, name="Helicoid"):
        r"""
        Returns a helicoid surface, with parametrization

        .. MATH::

            \begin{aligned}
              x(\rho, \theta) & = \rho \cos(\theta); \\
              y(\rho, \theta) & = \rho \sin(\theta); \\
              z(\rho, \theta) & = h\theta/(2\pi).
            \end{aligned}

        INPUT:

        - ``h`` -- distance along the z-axis between two
          successive turns of the helicoid.

        - ``name`` -- string. Name of the surface.

        EXAMPLES::

            sage: helicoid = surfaces.Helicoid(h=2); helicoid
            Parametrized surface ('Helicoid') with equation (rho*cos(theta), rho*sin(theta), theta/pi)
            sage: helicoid.plot()
            Graphics3d Object

        """

        rho, theta = var("rho, theta")
        helicoid_eq = [rho * cos(theta), rho * sin(theta), h * theta / (2 * pi)]
        coords = ((rho, -2, 2), (theta, 0, 2 * pi))

        return ParametrizedSurface3D(helicoid_eq, [rho, theta], name)
Пример #27
0
def _circ_arc(t0, t1, c, r, num_pts=500):
    r""" Circular arc
    INPUTS:
    - ''t0'' -- starting parameter
    - ''t1'' -- ending parameter
    - ''c''  -- center point of the circle
    - ''r''  -- radius of circle
    - ''num_pts''  -- (default 100) number of points on polygon
    OUTPUT:
    - ''ca'' -- a polygonal approximation of a circular arc centered
    at c and radius r, starting at t0 and ending at t1


    EXAMPLES::

        sage: ca=_circ_arc(0.1,0.2,0.0,1.0,100)

    """
    from sage.plot.plot import parametric_plot
    from sage.functions.trig import cos, sin
    from sage.all import var

    t00 = t0
    t11 = t1
    ## To make sure the line is correct we reduce all arguments to the same branch,
    ## e.g. [0,2pi]
    pi = RR.pi()
    while t00 < 0.0:
        t00 = t00 + RR(2.0 * pi)
    while t11 < 0:
        t11 = t11 + RR(2.0 * pi)
    while t00 > 2 * pi:
        t00 = t00 - RR(2.0 * pi)
    while t11 > 2 * pi:
        t11 = t11 - RR(2.0 * pi)

    xc = CC(c).real()
    yc = CC(c).imag()
    # L0 =
    # [[RR(r*cos(t00+i*(t11-t00)/num_pts))+xc,RR(r*sin(t00+i*(t11-t00)/num_pts))+yc]
    # for i in range(0 ,num_pts)]
    t = var("t")
    if t11 > t00:
        ca = parametric_plot((r * cos(t) + xc, r * sin(t) + yc), (t, t00, t11))
    else:
        ca = parametric_plot((r * cos(t) + xc, r * sin(t) + yc), (t, t11, t00))
    return ca
Пример #28
0
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES::

            sage: HyperbolicPlane().UHP().get_geodesic(0, 1).show()
            Graphics object consisting of 2 graphics primitives
        """
        opts = {'axes': False, 'aspect_ratio': 1}
        opts.update(self.graphics_options())
        opts.update(options)
        end_1, end_2 = [CC(k.coordinates()) for k in self.endpoints()]
        bd_1, bd_2 = [CC(k.coordinates()) for k in self.ideal_endpoints()]
        if (abs(real(end_1) - real(end_2)) < EPSILON) \
                or CC(infinity) in [end_1, end_2]: #on same vertical line
            # If one of the endpoints is infinity, we replace it with a
            # large finite  point
            if end_1 == CC(infinity):
                end_1 = (real(end_2), (imag(end_2) + 10))
                end_2 = (real(end_2), imag(end_2))
            elif end_2 == CC(infinity):
                end_2 = (real(end_1), (imag(end_1) + 10))
                end_1 = (real(end_1), imag(end_1))
            from sage.plot.line import line
            pic = line((end_1, end_2), **opts)
            if boundary:
                cent = min(bd_1, bd_2)
                bd_dict = {'bd_min': cent - 3, 'bd_max': cent + 3}
                bd_pic = self._model.get_background_graphic(**bd_dict)
                pic = bd_pic + pic
                return pic
        else:
            center = (bd_1 + bd_2)/2 # Circle center
            radius = abs(bd_1 - bd_2)/2
            theta1 = CC(end_1 - center).arg()
            theta2 = CC(end_2 - center).arg()
            if abs(theta1 - theta2) < EPSILON:
                theta2 += pi
            [theta1, theta2] = sorted([theta1, theta2])
            from sage.calculus.var import var
            from sage.plot.plot import parametric_plot
            x = var('x')
            pic = parametric_plot((radius*cos(x) + real(center),
                                   radius*sin(x) + imag(center)),
                                  (x, theta1, theta2), **opts)
            if boundary:
                # We want to draw a segment of the real line.  The
                # computations below compute the projection of the
                # geodesic to the real line, and then draw a little
                # to the left and right of the projection.
                shadow_1, shadow_2 = [real(k) for k in [end_1, end_2]]
                midpoint = (shadow_1 + shadow_2)/2
                length = abs(shadow_1 - shadow_2)
                bd_dict = {'bd_min': midpoint - length, 'bd_max': midpoint +
                           length}
                bd_pic = self._model.get_background_graphic(**bd_dict)
                pic = bd_pic + pic
            return pic
Пример #29
0
def _draw_funddom(coset_reps,format="S"):
    r""" Draw a fundamental domain for G.
    
    INPUT:
    
    - ``format``  -- (default 'Disp') How to present the f.d.
    -   ``S`` -- Display directly on the screen
    
    EXAMPLES::        


    sage: G=MySubgroup(Gamma0(3))
    sage: G._draw_funddom()
        
    """
    pi=RR.pi()
    pi_3 = pi / RR(3.0)
    from sage.plot.plot import (Graphics,line)
    from sage.functions.trig import (cos,sin)
    g=Graphics()
    x1=RR(-0.5) ; y1=RR(sqrt(3 )/2 )
    x2=RR(0.5) ; y2=RR(sqrt(3 )/2 )
    xmax=RR(20.0) 
    l1 = line([[x1,y1],[x1,xmax]])
    l2 = line([[x2,y2],[x2,xmax]])
    l3 = line([[x2,xmax],[x1,xmax]]) # This is added to make a closed contour
    c0=_circ_arc(RR(pi/3.0) ,RR(2.0*pi)/RR(3.0) ,0 ,1 ,100 )
    tri=c0+l1+l3+l2
    g=g+tri
    for A in coset_reps:
        [a,b,c,d]=A
        if(a==1  and b==0  and c==0  and d==1 ):
            continue
        if(a<0 ):
            a=RR(-a); b=RR(-b); c=RR(-c); d=RR(-d) 
        else:
            a=RR(a); b=RR(b); c=RR(c); d=RR(d) 
        if(c==0 ): # then this is easier
            L0 = [[cos(pi_3*RR(i/100.0))+b,sin(pi_3*RR(i/100.0))] for i in range(100 ,201 )]
            L1 = [[x1+b,y1],[x1+b,xmax]]
            L2 = [[x2+b,y2],[x2+b,xmax]]
            L3 = [[x2+b,xmax],[x1+b,xmax]]
            c0=line(L0); l1=line(L1); l2=line(L2); l3=line(L3)
            tri=c0+l1+l3+l2
            g=g+tri
        else:
            den=(c*x1+d)**2 +c**2 *y1**2 
            x1_t=(a*c*(x1**2 +y1**2 )+(a*d+b*c)*x1+b*d)/den
            y1_t=y1/den
            den=(c*x2+d)**2 +c**2 *y2**2 
            x2_t=(a*c*(x2**2 +y2**2 )+(a*d+b*c)*x2+b*d)/den
            y2_t=y2/den
            inf_t=a/c
            c0=_geodesic_between_two_points(x1_t,y1_t,x2_t,y2_t)
            c1=_geodesic_between_two_points(x1_t,y1_t,inf_t,0. )
            c2=_geodesic_between_two_points(x2_t,y2_t,inf_t,0.0)
            tri=c0+c1+c2
            g=g+tri
    return g
Пример #30
0
 def plot(self):
     from sage.functions.trig import sin, cos
     from sage.plot.circle import circle
     from sage.plot.point import point
     from sage.plot.text import text
     p = circle((0,0),1)
     for i in range(self._dimension):
         a = self._alpha[i]
         p += point([cos(2*pi*a),sin(2*pi*a)], color='blue', size=100)
         p += text(r"$\alpha_%i$"%(self._i_alpha[i]+1),
                   [1.2*cos(2*pi*a),1.2*sin(2*pi*a)],fontsize=40)
     for i in range(self._dimension):
         b = self._beta[i]
         p += point([cos(2*pi*b),sin(2*pi*b)], color='red', size=100)
         p += text(r"$\beta_%i$"%(self._i_beta[i]+1),
                   [1.2*cos(2*pi*b),1.2*sin(2*pi*b)],fontsize=40)
     p.show(axes=False, xmin=-1, xmax=1, ymin=-1, ymax=1)
Пример #31
0
def _circ_arc(t0, t1, c, r, num_pts=5000):
    r""" Circular arc
    INPUTS:
    - ''t0'' -- starting parameter
    - ''t1'' -- ending parameter
    - ''c''  -- center point of the circle
    - ''r''  -- radius of circle
    - ''num_pts''  -- (default 100) number of points on polygon
    OUTPUT:
    - ''ca'' -- a polygonal approximation of a circular arc centered
    at c and radius r, starting at t0 and ending at t1

    
    EXAMPLES::

        sage: ca=_circ_arc(0.1,0.2,0.0,1.0,100)
    
    """
    from sage.plot.plot import line, parametric_plot
    from sage.functions.trig import (cos, sin)
    from sage.all import var
    t00 = t0
    t11 = t1
    ## To make sure the line is correct we reduce all arguments to the same branch,
    ## e.g. [0,2pi]
    pi = RR.pi()
    while (t00 < 0.0):
        t00 = t00 + RR(2.0 * pi)
    while (t11 < 0):
        t11 = t11 + RR(2.0 * pi)
    while (t00 > 2 * pi):
        t00 = t00 - RR(2.0 * pi)
    while (t11 > 2 * pi):
        t11 = t11 - RR(2.0 * pi)

    xc = CC(c).real()
    yc = CC(c).imag()
    num_pts = 3
    t = var('t')
    if t11 > t00:
        ca = parametric_plot((r * cos(t) + xc, r * sin(t) + yc), (t, t00, t11))
    else:
        ca = parametric_plot((r * cos(t) + xc, r * sin(t) + yc), (t, t11, t00))
    #L0 = [[RR(r*cos(t00+i*(t11-t00)/num_pts))+xc,RR(r*sin(t00+i*(t11-t00)/num_pts))+yc] for i in range(0 ,num_pts)]
    #ca=line(L0)
    return ca
Пример #32
0
    def plot(self, show_box=False, colors=["white","lightgray","darkgray"]):
        r"""
        Return a plot of ``self``.

        INPUT:

        - ``show_box`` -- boolean (default: ``False``); if ``True``,
          also shows the visible tiles on the `xy`-, `yz`-, `zx`-planes

        - ``colors`` -- (default: ``["white", "lightgray", "darkgray"]``)
          list ``[A, B, C]`` of 3 strings representing colors

        EXAMPLES::

            sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]])
            sage: PP.plot()
            Graphics object consisting of 27 graphics primitives
        """
        x = self._max_x
        y = self._max_y
        z = self._max_z
        from sage.functions.trig import cos, sin
        from sage.plot.polygon import polygon
        from sage.symbolic.constants import pi
        from sage.plot.plot import plot
        Uside = [[0,0], [cos(-pi/6),sin(-pi/6)], [0,-1], [cos(7*pi/6),sin(7*pi/6)]]
        Lside = [[0,0], [cos(-pi/6),sin(-pi/6)], [cos(pi/6),sin(pi/6)], [0,1]]
        Rside = [[0,0], [0,1], [cos(5*pi/6),sin(5*pi/6)], [cos(7*pi/6),sin(7*pi/6)]]
        Xdir = [cos(7*pi/6), sin(7*pi/6)]
        Ydir = [cos(-pi/6), sin(-pi/6)]
        Zdir = [0, 1]
        def move(side, i, j, k):
            return [[P[0]+i*Xdir[0]+j*Ydir[0]+k*Zdir[0],
                     P[1]+i*Xdir[1]+j*Ydir[1]+k*Zdir[1]]
                    for P in side]
        def add_topside(i, j, k):
            return polygon(move(Uside,i,j,k), edgecolor="black", color=colors[0])
        def add_leftside(i, j, k):
            return polygon(move(Lside,i,j,k), edgecolor="black", color=colors[1])
        def add_rightside(i, j, k):
            return polygon(move(Rside,i,j,k), edgecolor="black", color=colors[2])
        TP = plot([])
        for r in range(len(self.z_tableau())):
            for c in range(len(self.z_tableau()[r])):
                if self.z_tableau()[r][c] > 0 or show_box:
                    TP += add_topside(r, c, self.z_tableau()[r][c])
        for r in range(len(self.y_tableau())):
            for c in range(len(self.y_tableau()[r])):
                if self.y_tableau()[r][c] > 0 or show_box:
                    TP += add_rightside(c, self.y_tableau()[r][c], r)
        for r in range(len(self.x_tableau())):
            for c in range(len(self.x_tableau()[r])):
                if self.x_tableau()[r][c] > 0 or show_box:
                    TP += add_leftside(self.x_tableau()[r][c], r, c)
        TP.axes(show=False)
        return TP
    def __init__(self, sides, i_angle, center, options):
        """
        Initialize HyperbolicRegularPolygon.

        EXAMPLES::

            sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
            sage: print(HyperbolicRegularPolygon(5,pi/2,I, {}))
            Hyperbolic regular polygon (sides=5, i_angle=1/2*pi, center=1.00000000000000*I)
        """
        self.center = CC(center)
        if self.center.imag() <= 0 :
            raise ValueError("center: %s is not a valid point in the upper half plane model of the hyperbolic plane"%(self.center))
        if sides < 3 :
            raise ValueError("degenerated polygons (sides<=2) are not supported")
        if i_angle <=0 or i_angle >= pi:
            raise ValueError("interior angle %s must be in (0, pi) interval"%(i_angle))
        if pi*(sides-2) - sides*i_angle <= 0 :
            raise ValueError("there exists no hyperbolic regular compact polygon, for sides=%s the interior angle must be less than %s"%(sides, pi * (sides-2) / sides))
        self.sides = sides
        self.i_angle = i_angle
        beta = 2 * pi / self.sides # compute the rotation angle to be used ahead
        alpha = self.i_angle / Integer(2)
        I = CC(0, 1)
        # compute using cosine theorem the radius of the circumscribed circle
        # using the triangle formed by the radius and the three known angles
        r = arccosh(cot(alpha) * (1 + cos(beta)) / sin(beta))

        # The first point will be always on the imaginary axis limited
        # to 8 digits for efficiency in the subsequent calculations.
        z_0 = [I*(e**r).n(digits=8)]

        # Compute the dilation isometry used to move the center
        # from I to the imaginary part of the given center.
        scale = self.center.imag()

        # Compute the parabolic isometry to move the center to the
        # real part of the given center.
        h_disp = self.center.real()

        d_z_k = [z_0[0]*scale + h_disp]  #d_k has the points for the polygon in the given center
        z_k = z_0                      #z_k has the Re(z)>0 vertices for the I centered polygon 
        r_z_k = []                     #r_z_k has the Re(z)<0 vertices
        if is_odd(self.sides):
            vert = (self.sides - 1) / 2
        else:
            vert = self.sides / 2 - 1
        for k in range(0, vert):
            # Compute with 8 digits to accelerate calculations
            new_z_k = self._i_rotation(z_k[-1], beta).n(digits=8)
            z_k = z_k + [new_z_k]
            d_z_k = d_z_k + [new_z_k * scale + h_disp]
            r_z_k=[-(new_z_k).conjugate() * scale + h_disp] + r_z_k
        if is_odd(self.sides):
            HyperbolicPolygon.__init__(self, d_z_k + r_z_k, options)
        else:
            z_opo = [I * (e**(-r)).n(digits=8) * scale + h_disp]
            HyperbolicPolygon.__init__(self, d_z_k + z_opo + r_z_k, options)
    def plot(self, **kwargs):
        """
        Return a graphics object representing the Kontsevich graph.

        INPUT:

        - ``edge_labels`` (boolean, default True) -- if True, show edge labels.
        - ``indices`` (boolean, default False) -- if True, show indices as
          edge labels instead of L and R; see :meth:`._latex_`.
        - ``upright`` (boolean, default False) -- if True, try to plot the
          graph with the ground vertices on the bottom and the rest on top.
        """
        if not 'edge_labels' in kwargs:
            kwargs['edge_labels'] = True        # show edge labels by default
        if 'indices' in kwargs:
            del kwargs['indices']
            KG = DiGraph(self)
            for (k,e) in enumerate(self.edges()):
                KG.delete_edge(e)
                KG.add_edge((e[0], e[1], chr(97 + k)))
            return KG.plot(**kwargs)
        if len(self.ground_vertices()) == 2 and 'upright' in kwargs:
            del kwargs['upright']
            kwargs['save_pos'] = True
            DiGraph.plot(self, **kwargs)
            positions = self.get_pos()
            # translate F to origin:
            F_pos = vector(positions[self.ground_vertices()[0]])
            for p in positions:
                positions[p] = list(vector(positions[p]) - F_pos)
            # scale F - G distance to 1:
            G_len = abs(vector(positions[self.ground_vertices()[1]]))
            for p in positions:
                positions[p] = list(vector(positions[p])/G_len)
            # rotate the vector F - G to (1,0)
            from math import atan2
            theta = -atan2(positions[self.ground_vertices()[1]][1], positions[self.ground_vertices()[1]][0])
            for p in positions:
                positions[p] = list(matrix([[cos(theta),-(sin(theta))],[sin(theta),cos(theta)]]) * vector(positions[p]))
            # flip if most things are below the x-axis:
            if len([(x,y) for (x,y) in positions.values() if y < 0])/len(self.internal_vertices()) > 0.5:
                for p in positions:
                    positions[p] = [positions[p][0], -positions[p][1]]
        return DiGraph.plot(self, **kwargs)
Пример #35
0
def draw_transformed_triangle_H(A, xmax=20):
    r"""
    Draw the modular triangle translated by A=[a,b,c,d]
    """
    #print "A=",A,type(A)
    pi = RR.pi()
    pi_3 = pi / RR(3.0)
    from sage.plot.plot import (Graphics, line)
    from sage.functions.trig import (cos, sin)
    x1 = RR(-0.5)
    y1 = RR(sqrt(3) / 2)
    x2 = RR(0.5)
    y2 = RR(sqrt(3) / 2)
    a, b, c, d = A  #[0,0]; b=A[0,1]; c=A[1,0]; d=A[1,1]
    if a < 0:
        a = RR(-a)
        b = RR(-b)
        c = RR(-c)
        d = RR(-d)
    else:
        a = RR(a)
        b = RR(b)
        c = RR(c)
        d = RR(d)
    if c == 0:  # then this is easier
        if a * d <> 0:
            a = a / d
            b = b / d
        L0 = [[
            a * cos(pi_3 * RR(i / 100.0)) + b, a * sin(pi_3 * RR(i / 100.0))
        ] for i in range(100, 201)]
        L1 = [[a * x1 + b, a * y1], [a * x1 + b, xmax]]
        L2 = [[a * x2 + b, a * y2], [a * x2 + b, xmax]]
        L3 = [[a * x2 + b, xmax], [a * x1 + b, xmax]]
        c0 = line(L0)
        l1 = line(L1)
        l2 = line(L2)
        l3 = line(L3)
        tri = c0 + l1 + l3 + l2
    else:
        den = (c * x1 + d)**2 + c**2 * y1**2
        x1_t = (a * c * (x1**2 + y1**2) + (a * d + b * c) * x1 + b * d) / den
        y1_t = y1 / den
        den = (c * x2 + d)**2 + c**2 * y2**2
        x2_t = (a * c * (x2**2 + y2**2) + (a * d + b * c) * x2 + b * d) / den
        y2_t = y2 / den
        inf_t = a / c
        #print "A=",A
        #print "arg1=",x1_t,y1_t,x2_t,y2_t
        c0 = _geodesic_between_two_points(x1_t, y1_t, x2_t, y2_t)
        #print "arg1=",x1_t,y1_t,inf_t
        c1 = _geodesic_between_two_points(x1_t, y1_t, inf_t, 0.)
        #print "arg1=",x2_t,y2_t,inf_t
        c2 = _geodesic_between_two_points(x2_t, y2_t, inf_t, 0.0)
        tri = c0 + c1 + c2
    return tri
Пример #36
0
    def _derivative_(self, x, diff_param=None):
        """
        EXAMPLES::

            sage: x = var('x')
            sage: fresnel_sin(x).diff(x)
            sin(1/2*pi*x^2)
        """
        from sage.functions.trig import sin
        return sin(pi*x**2/2)
Пример #37
0
 def map_to_Euclidean(self):
     r"""
     Map from Kerr spacetime to the Euclidean 4-space, based on
     Boyer-Lindquist coordinates
     """
     if self._map_to_E4 is None:
         E4 = EuclideanSpace(4,
                             coordinates='Cartesian',
                             symbols='t x y z',
                             start_index=0)
         X4 = E4.cartesian_coordinates()
         BL = self.boyer_lindquist_coordinates()
         t, r, th, ph = BL[:]
         self._map_to_E4 = self.diff_map(E4, {
             (BL, X4):
             [t, r * sin(th) * cos(ph), r * sin(th) * sin(ph), r * cos(th)]
         },
                                         name='F')
     return self._map_to_E4
Пример #38
0
    def _derivative_(self, x, diff_param=None):
        """
        EXAMPLES::

            sage: x = var('x')
            sage: fresnel_sin(x).diff(x)
            sin(1/2*pi*x^2)
        """
        from sage.functions.trig import sin
        return sin(pi * x**2 / 2)
Пример #39
0
    def transform(self, radius=None, azimuth=None, height=None):
        """
        A cylindrical coordinates transform.

        EXAMPLES::

            sage: T = Cylindrical('height', ['azimuth', 'radius'])
            sage: T.transform(radius=var('r'), azimuth=var('theta'), height=var('z'))
            (r*cos(theta), r*sin(theta), z)
        """
        return (radius * cos(azimuth), radius * sin(azimuth), height)
Пример #40
0
    def Ellipsoid(center=(0,0,0), axes=(1,1,1), name="Ellipsoid"):
        r"""
        Returns an ellipsoid centered at ``center`` whose semi-principal axes
        have lengths given by the components of ``axes``. The
        parametrization of the ellipsoid is given by

        .. MATH::

            \begin{aligned}
              x(u, v) & = x_0 + a \cos(u) \cos(v); \\
              y(u, v) & = y_0 + b \sin(u) \cos(v); \\
              z(u, v) & = z_0 + c \sin(v).
            \end{aligned}

        INPUT:

        - ``center`` -- 3-tuple. Coordinates of the center of the ellipsoid.

        - ``axes`` -- 3-tuple. Lengths of the semi-principal axes.

        - ``name`` -- string. Name of the ellipsoid.

        EXAMPLES::

            sage: ell = surfaces.Ellipsoid(axes=(1, 2, 3)); ell
            Parametrized surface ('Ellipsoid') with equation (cos(u)*cos(v), 2*cos(v)*sin(u), 3*sin(v))
            sage: ell.plot()
            Graphics3d Object

        """

        u, v = var ('u, v')
        x, y, z = center
        a, b, c = axes
        ellipsoid_parametric_eq = [x + a*cos(u)*cos(v),
                                   y + b*sin(u)*cos(v),
                                   z + c*sin(v)]
        coords = ((u, 0, 2*pi), (v, -pi/2, pi/2))

        return ParametrizedSurface3D(ellipsoid_parametric_eq, coords, name)
Пример #41
0
    def transform(self, radius=None, azimuth=None, height=None):
        """
        A cylindrical coordinates transform.

        EXAMPLE::

            sage: T = Cylindrical('height', ['azimuth', 'radius'])
            sage: T.transform(radius=var('r'), azimuth=var('theta'), height=var('z'))
            (r*cos(theta), r*sin(theta), z)
        """
        return (radius * cos(azimuth),
                radius * sin(azimuth),
                height)
Пример #42
0
    def Ellipsoid(center=(0,0,0), axes=(1,1,1), name="Ellipsoid"):
        r"""
        Returns an ellipsoid centered at ``center`` whose semi-principal axes
        have lengths given by the components of ``axes``. The
        parametrization of the ellipsoid is given by

        .. MATH::

            \begin{aligned}
              x(u, v) & = x_0 + a \cos(u) \cos(v); \\
              y(u, v) & = y_0 + b \sin(u) \cos(v); \\
              z(u, v) & = z_0 + c \sin(v).
            \end{aligned}

        INPUT:

        - ``center`` -- 3-tuple. Coordinates of the center of the ellipsoid.

        - ``axes`` -- 3-tuple. Lengths of the semi-principal axes.

        - ``name`` -- string. Name of the ellipsoid.

        EXAMPLES::

            sage: ell = surfaces.Ellipsoid(axes=(1, 2, 3)); ell
            Parametrized surface ('Ellipsoid') with equation (cos(u)*cos(v), 2*cos(v)*sin(u), 3*sin(v))
            sage: ell.plot()

        """

        u, v = var ('u, v')
        x, y, z = center
        a, b, c = axes
        ellipsoid_parametric_eq = [x + a*cos(u)*cos(v),
                                   y + b*sin(u)*cos(v),
                                   z + c*sin(v)]
        coords = ((u, 0, 2*pi), (v, -pi/2, pi/2))

        return ParametrizedSurface3D(ellipsoid_parametric_eq, coords, name)
Пример #43
0
 def plot(self):
     from sage.functions.trig import sin, cos
     from sage.plot.circle import circle
     from sage.plot.point import point
     from sage.plot.text import text
     p = circle((0, 0), 1)
     for i in range(self._dimension):
         a = self._alpha[i]
         p += point([cos(2 * pi * a), sin(2 * pi * a)],
                    color='blue',
                    size=100)
         p += text(r"$\alpha_%i$" % (self._i_alpha[i] + 1),
                   [1.2 * cos(2 * pi * a), 1.2 * sin(2 * pi * a)],
                   fontsize=40)
     for i in range(self._dimension):
         b = self._beta[i]
         p += point([cos(2 * pi * b), sin(2 * pi * b)],
                    color='red',
                    size=100)
         p += text(r"$\beta_%i$" % (self._i_beta[i] + 1),
                   [1.2 * cos(2 * pi * b), 1.2 * sin(2 * pi * b)],
                   fontsize=40)
     p.show(axes=False, xmin=-1, xmax=1, ymin=-1, ymax=1)
Пример #44
0
    def triangulation(self):
        r"""
        Plot a regular polygon with some diagonals.

        If ``self`` is positive and integral then this will be a triangulation.

        .. PLOT::
            :width: 600 px

            G = path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]).triangulation()
            p = graphics_array(G, 7, 6)
            sphinx_plot(p)

        EXAMPLES::

            sage: path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]).triangulation()
            Graphics object consisting of 25 graphics primitives

            sage: path_tableaux.FriezePattern([1,2,1/7,5,3]).triangulation()
            Graphics object consisting of 12 graphics primitives

            sage: K.<sqrt2> = NumberField(x^2-2)
            sage: path_tableaux.FriezePattern([1,sqrt2,1,sqrt2,3,2*sqrt2,5,3*sqrt2,1], field=K).triangulation()
            Graphics object consisting of 24 graphics primitives
        """
        n = len(self) - 1
        cd = CylindricalDiagram(self).diagram
        from sage.plot.plot import Graphics
        from sage.plot.line import line
        from sage.plot.text import text
        from sage.functions.trig import sin, cos
        from sage.all import pi
        G = Graphics()
        G.set_aspect_ratio(1.0)

        vt = [(cos(2 * theta * pi / (n)), sin(2 * theta * pi / (n)))
              for theta in range(n + 1)]
        for i, p in enumerate(vt):
            G += text(str(i), [1.05 * p[0], 1.05 * p[1]])

        for i, r in enumerate(cd):
            for j, a in enumerate(r[:n]):
                if a == 1:
                    G += line([vt[i], vt[j]])

        G.axes(False)
        return G
Пример #45
0
    def _derivative_(self, z, diff_param=None):
        r"""
        The derivative of `\operatorname{Si}(z)` is `\sin(z)/z` if `z`
        is not zero. The derivative at `z = 0` is `1` (but this
        exception is not currently implemented).

        EXAMPLES::

            sage: x = var('x')
            sage: f = sin_integral(x)
            sage: f.diff(x)
            sin(x)/x

            sage: f = sin_integral(x^2)
            sage: f.diff(x)
            2*sin(x^2)/x

        """
        return sin(z)/z
Пример #46
0
    def _derivative_(self, z, diff_param=None):
        r"""
        The derivative of `\operatorname{Si}(z)` is `\sin(z)/z` if `z`
        is not zero. The derivative at `z = 0` is `1` (but this
        exception is not currently implemented).

        EXAMPLES::

            sage: x = var('x')
            sage: f = sin_integral(x)
            sage: f.diff(x)
            sin(x)/x

            sage: f = sin_integral(x^2)
            sage: f.diff(x)
            2*sin(x^2)/x

        """
        return sin(z) / z
Пример #47
0
def draw_transformed_triangle_H(A,xmax=20):
    r"""
    Draw the modular triangle translated by A=[a,b,c,d]
    """
    #print "A=",A,type(A)
    pi=RR.pi()
    pi_3 = pi / RR(3.0)
    from sage.plot.plot import (Graphics,line)
    from sage.functions.trig import (cos,sin)
    x1=RR(-0.5) ; y1=RR(sqrt(3 )/2 )
    x2=RR(0.5) ; y2=RR(sqrt(3 )/2 )
    a,b,c,d = A #[0,0]; b=A[0,1]; c=A[1,0]; d=A[1,1]
    if a<0:
        a=RR(-a); b=RR(-b); c=RR(-c); d=RR(-d) 
    else:
        a=RR(a); b=RR(b); c=RR(c); d=RR(d) 
    if c==0: # then this is easier
        if a*d<>0:
            a=a/d; b=b/d; 
        L0 = [[a*cos(pi_3*RR(i/100.0))+b,a*sin(pi_3*RR(i/100.0))] for i in range(100 ,201 )]
        L1 = [[a*x1+b,a*y1],[a*x1+b,xmax]]
        L2 = [[a*x2+b,a*y2],[a*x2+b,xmax]]
        L3 = [[a*x2+b,xmax],[a*x1+b,xmax]]
        c0=line(L0); l1=line(L1); l2=line(L2); l3=line(L3)
        tri=c0+l1+l3+l2
    else:
        den=(c*x1+d)**2 +c**2 *y1**2 
        x1_t=(a*c*(x1**2 +y1**2 )+(a*d+b*c)*x1+b*d)/den
        y1_t=y1/den
        den=(c*x2+d)**2 +c**2 *y2**2 
        x2_t=(a*c*(x2**2 +y2**2 )+(a*d+b*c)*x2+b*d)/den
        y2_t=y2/den
        inf_t=a/c
        #print "A=",A
        #print "arg1=",x1_t,y1_t,x2_t,y2_t
        c0=_geodesic_between_two_points(x1_t,y1_t,x2_t,y2_t)
        #print "arg1=",x1_t,y1_t,inf_t
        c1=_geodesic_between_two_points(x1_t,y1_t,inf_t,0. )
        #print "arg1=",x2_t,y2_t,inf_t
        c2=_geodesic_between_two_points(x2_t,y2_t,inf_t,0.0)
        tri=c0+c1+c2
    return tri
Пример #48
0
    def regular_polygon(self, n, base_ring=QQ):
        """
        Return a regular polygon with n vertices.  Over the rational
        field the vertices may not be exact.

        INPUT:

        - ``n`` -- a positive integer, the number of vertices.

        - ``field`` -- either ``QQ`` or ``RDF``.

        EXAMPLES::

            sage: octagon = polytopes.regular_polygon(8)
            sage: len(octagon.vertices())
            8
        """
        npi = 3.14159265359
        verts = []
        for i in range(n):
            t = 2*npi*i/n
            verts.append([sin(t),cos(t)])
        verts = [[base_ring(RDF(x)) for x in y] for y in verts]
        return Polyhedron(vertices=verts, base_ring=base_ring)
Пример #49
0
    def regular_polygon(self, n, base_ring=QQ):
        """
        Return a regular polygon with n vertices.  Over the rational
        field the vertices may not be exact.

        INPUT:

        - ``n`` -- a positive integer, the number of vertices.

        - ``field`` -- either ``QQ`` or ``RDF``.

        EXAMPLES::

            sage: octagon = polytopes.regular_polygon(8)
            sage: len(octagon.vertices())
            8
        """
        npi = 3.14159265359
        verts = []
        for i in range(n):
            t = 2 * npi * i / n
            verts.append([sin(t), cos(t)])
        verts = [[base_ring(RDF(x)) for x in y] for y in verts]
        return Polyhedron(vertices=verts, base_ring=base_ring)
Пример #50
0
def revolution_plot3d(curve,
                      trange,
                      phirange=None,
                      parallel_axis='z',
                      axis=(0, 0),
                      print_vector=False,
                      show_curve=False,
                      **kwds):
    """
    Return a plot of a revolved curve.

    There are three ways to call this function:

    - ``revolution_plot3d(f,trange)`` where `f` is a function located in the `x z` plane.

    - ``revolution_plot3d((f_x,f_z),trange)`` where `(f_x,f_z)` is a parametric curve on the `x z` plane.

    - ``revolution_plot3d((f_x,f_y,f_z),trange)`` where `(f_x,f_y,f_z)` can be any parametric curve.

    INPUT:

    - ``curve`` - A curve to be revolved, specified as a function, a 2-tuple or a 3-tuple.

    - ``trange`` - A 3-tuple `(t,t_{\min},t_{\max})` where t is the independent variable of the curve.

    - ``phirange`` - A 2-tuple of the form `(\phi_{\min},\phi_{\max})`, (default `(0,\pi)`) that specifies the angle in which the curve is to be revolved.

    - ``parallel_axis`` - A string (Either 'x', 'y', or 'z') that specifies the coordinate axis parallel to the revolution axis.

    - ``axis`` - A 2-tuple that specifies the position of the revolution axis. If parallel is:

        - 'z' - then axis is the point in which the revolution axis intersects the  `x y` plane.

        - 'x' - then axis is the point in which the revolution axis intersects the  `y z` plane.

        - 'y' - then axis is the point in which the revolution axis intersects the `x z` plane.

    - ``print_vector`` - If True, the parametrization of the surface of revolution will be printed.

    - ``show_curve`` - If True, the curve will be displayed.


    EXAMPLES:

    Let's revolve a simple function around different axes::

        sage: u = var('u')
        sage: f=u^2
        sage: revolution_plot3d(f,(u,0,2),show_curve=True,opacity=0.7).show(aspect_ratio=(1,1,1))

    If we move slightly the axis, we get a goblet-like surface::

        sage: revolution_plot3d(f,(u,0,2),axis=(1,0.2),show_curve=True,opacity=0.5).show(aspect_ratio=(1,1,1))

    A common problem in calculus books, find the volume within the following revolution solid::

        sage: line=u
        sage: parabola=u^2
        sage: sur1=revolution_plot3d(line,(u,0,1),opacity=0.5,rgbcolor=(1,0.5,0),show_curve=True,parallel_axis='x')
        sage: sur2=revolution_plot3d(parabola,(u,0,1),opacity=0.5,rgbcolor=(0,1,0),show_curve=True,parallel_axis='x')
        sage: (sur1+sur2).show()


    Now let's revolve a parametrically defined circle. We can play with the topology of the surface by changing the axis, an axis in `(0,0)` (as the previous one) will produce a sphere-like surface::

        sage: u = var('u')
        sage: circle=(cos(u),sin(u))
        sage: revolution_plot3d(circle,(u,0,2*pi),axis=(0,0),show_curve=True,opacity=0.5).show(aspect_ratio=(1,1,1))

    An axis on `(0,y)` will produce a cylinder-like surface::

        sage: revolution_plot3d(circle,(u,0,2*pi),axis=(0,2),show_curve=True,opacity=0.5).show(aspect_ratio=(1,1,1))

    And any other axis will produce a torus-like surface::

        sage: revolution_plot3d(circle,(u,0,2*pi),axis=(2,0),show_curve=True,opacity=0.5).show(aspect_ratio=(1,1,1))

    Now, we can get another goblet-like surface by revolving a curve in 3d::

        sage: u = var('u')
        sage: curve=(u,cos(4*u),u^2)
        sage: revolution_plot3d(curve,(u,0,2),show_curve=True,parallel_axis='z',axis=(1,.2),opacity=0.5).show(aspect_ratio=(1,1,1))

    A curvy curve with only a quarter turn::

        sage: u = var('u')
        sage: curve=(sin(3*u),.8*cos(4*u),cos(u))
        sage: revolution_plot3d(curve,(u,0,pi),(0,pi/2),show_curve=True,parallel_axis='z',opacity=0.5).show(aspect_ratio=(1,1,1),frame=False)
    """
    from sage.symbolic.ring import SR
    from sage.symbolic.constants import pi
    from sage.functions.other import sqrt
    from sage.functions.trig import sin
    from sage.functions.trig import cos
    from sage.functions.trig import atan2

    if parallel_axis not in ['x', 'y', 'z']:
        raise ValueError("parallel_axis must be either 'x', 'y', or 'z'.")

    vart = trange[0]

    if str(vart) == 'phi':
        phi = SR.var('fi')
    else:
        phi = SR.var('phi')

    if phirange is None:  #this if-else provides a phirange
        phirange = (phi, 0, 2 * pi)
    elif len(phirange) == 3:
        phi = phirange[0]
        pass
    else:
        phirange = (phi, phirange[0], phirange[1])

    if isinstance(curve, tuple) or isinstance(curve, list):
        #this if-else provides a vector v to be plotted
        #if curve is a tuple or a list of length 2, it is interpreted as a parametric curve
        #in the x-z plane.
        #if it is of length 3 it is interpreted as a parametric curve in 3d space

        if len(curve) == 2:
            x = curve[0]
            y = 0
            z = curve[1]
        elif len(curve) == 3:
            x = curve[0]
            y = curve[1]
            z = curve[2]
    else:
        x = vart
        y = 0
        z = curve

    if parallel_axis == 'z':
        x0 = axis[0]
        y0 = axis[1]
        # (0,0) must be handled separately for the phase value
        phase = 0
        if x0 != 0 or y0 != 0:
            phase = atan2((y - y0), (x - x0))
        R = sqrt((x - x0)**2 + (y - y0)**2)
        v = (R * cos(phi + phase) + x0, R * sin(phi + phase) + y0, z)
    elif parallel_axis == 'x':
        y0 = axis[0]
        z0 = axis[1]
        # (0,0) must be handled separately for the phase value
        phase = 0
        if z0 != 0 or y0 != 0:
            phase = atan2((z - z0), (y - y0))
        R = sqrt((y - y0)**2 + (z - z0)**2)
        v = (x, R * cos(phi + phase) + y0, R * sin(phi + phase) + z0)
    elif parallel_axis == 'y':
        x0 = axis[0]
        z0 = axis[1]
        # (0,0) must be handled separately for the phase value
        phase = 0
        if z0 != 0 or x0 != 0:
            phase = atan2((z - z0), (x - x0))
        R = sqrt((x - x0)**2 + (z - z0)**2)
        v = (R * cos(phi + phase) + x0, y, R * sin(phi + phase) + z0)

    if print_vector:
        print(v)
    if show_curve:
        curveplot = parametric_plot3d((x, y, z),
                                      trange,
                                      thickness=2,
                                      rgbcolor=(1, 0, 0))
        return parametric_plot3d(v, trange, phirange, **kwds) + curveplot
    return parametric_plot3d(v, trange, phirange, **kwds)
Пример #51
0
def subexpressions_list(f, pars=None):
    """
    Construct the lists with the intermediate steps on the evaluation of the
    function.

    INPUT:

    - ``f`` -- a symbolic function of several components.

    - ``pars`` -- a list of the parameters that appear in the function
      this should be the symbolic constants that appear in f but are not
      arguments.

    OUTPUT:

    - a list of the intermediate subexpressions that appear in the evaluation
      of f.

    - a list with the operations used to construct each of the subexpressions.
      each element of this list is a tuple, formed by a string describing the
      operation made, and the operands.

    For the trigonometric functions, some extra expressions will be added.
    These extra expressions will be used later to compute their derivatives.


    EXAMPLES::

        sage: from sage.interfaces.tides import subexpressions_list
        sage: var('x,y')
        (x, y)
        sage: f(x,y) = [x^2+y, cos(x)/log(y)]
        sage: subexpressions_list(f)
        ([x^2, x^2 + y, sin(x), cos(x), log(y), cos(x)/log(y)],
        [('mul', x, x),
        ('add', y, x^2),
        ('sin', x),
        ('cos', x),
        ('log', y),
        ('div', log(y), cos(x))])

    ::

        sage: f(a)=[cos(a), arctan(a)]
        sage: from sage.interfaces.tides import subexpressions_list
        sage: subexpressions_list(f)
        ([sin(a), cos(a), a^2, a^2 + 1, arctan(a)],
        [('sin', a), ('cos', a), ('mul', a, a), ('add', 1, a^2), ('atan', a)])

    ::

        sage: from sage.interfaces.tides import subexpressions_list
        sage: var('s,b,r')
        (s, b, r)
        sage: f(t,x,y,z)= [s*(y-x),x*(r-z)-y,x*y-b*z]
        sage: subexpressions_list(f,[s,b,r])
        ([-y,
        x - y,
        s*(x - y),
        -s*(x - y),
        -z,
        r - z,
        (r - z)*x,
        -y,
        (r - z)*x - y,
        x*y,
        b*z,
        -b*z,
        x*y - b*z],
        [('mul', -1, y),
        ('add', -y, x),
        ('mul', x - y, s),
        ('mul', -1, s*(x - y)),
        ('mul', -1, z),
        ('add', -z, r),
        ('mul', x, r - z),
        ('mul', -1, y),
        ('add', -y, (r - z)*x),
        ('mul', y, x),
        ('mul', z, b),
        ('mul', -1, b*z),
        ('add', -b*z, x*y)])

    ::

        sage: var('x, y')
        (x, y)
        sage: f(x,y)=[exp(x^2+sin(y))]
        sage: from sage.interfaces.tides import *
        sage: subexpressions_list(f)
        ([x^2, sin(y), cos(y), x^2 + sin(y), e^(x^2 + sin(y))],
        [('mul', x, x),
        ('sin', y),
        ('cos', y),
        ('add', sin(y), x^2),
        ('exp', x^2 + sin(y))])


    """
    from sage.functions.trig import sin, cos, arcsin, arctan, arccos
    variables = f[0].arguments()
    if not pars:
        parameters = []
    else:
        parameters = pars
    varpar = list(parameters) + list(variables)
    F = symbolic_expression([i(*variables) for i in f]).function(*varpar)
    lis = flatten([fast_callable(i,vars=varpar).op_list() for i in F], max_level=1)
    stack = []
    const =[]
    stackcomp=[]
    detail=[]
    for i in lis:
        if i[0] == 'load_arg':
            stack.append(varpar[i[1]])
        elif i[0] == 'ipow':
            if i[1] in NN:
                basis = stack[-1]
                for j in range(i[1]-1):
                    a=stack.pop(-1)
                    detail.append(('mul', a, basis))
                    stack.append(a*basis)
                    stackcomp.append(stack[-1])
            else:
                detail.append(('pow',stack[-1],i[1]))
                stack[-1]=stack[-1]**i[1]
                stackcomp.append(stack[-1])

        elif i[0] == 'load_const':
            const.append(i[1])
            stack.append(i[1])
        elif i == 'mul':
            a=stack.pop(-1)
            b=stack.pop(-1)
            detail.append(('mul', a, b))
            stack.append(a*b)
            stackcomp.append(stack[-1])

        elif i == 'div':
            a=stack.pop(-1)
            b=stack.pop(-1)
            detail.append(('div', a, b))
            stack.append(b/a)
            stackcomp.append(stack[-1])

        elif i == 'add':
            a=stack.pop(-1)
            b=stack.pop(-1)
            detail.append(('add',a,b))
            stack.append(a+b)
            stackcomp.append(stack[-1])

        elif i == 'pow':
            a=stack.pop(-1)
            b=stack.pop(-1)
            detail.append(('pow', b, a))
            stack.append(b**a)
            stackcomp.append(stack[-1])

        elif i[0] == 'py_call' and str(i[1])=='log':
            a=stack.pop(-1)
            detail.append(('log', a))
            stack.append(log(a))
            stackcomp.append(stack[-1])

        elif i[0] == 'py_call' and str(i[1])=='exp':
            a=stack.pop(-1)
            detail.append(('exp', a))
            stack.append(exp(a))
            stackcomp.append(stack[-1])

        elif i[0] == 'py_call' and str(i[1])=='sin':
            a=stack.pop(-1)
            detail.append(('sin', a))
            detail.append(('cos', a))
            stackcomp.append(sin(a))
            stackcomp.append(cos(a))
            stack.append(sin(a))

        elif i[0] == 'py_call' and str(i[1])=='cos':
            a=stack.pop(-1)
            detail.append(('sin', a))
            detail.append(('cos', a))
            stackcomp.append(sin(a))
            stackcomp.append(cos(a))
            stack.append(cos(a))

        elif i[0] == 'py_call' and str(i[1])=='tan':
            a=stack.pop(-1)
            b = sin(a)
            c = cos(a)
            detail.append(('sin', a))
            detail.append(('cos', a))
            detail.append(('div', b, c))
            stackcomp.append(b)
            stackcomp.append(c)
            stackcomp.append(b/c)
            stack.append(b/c)

        elif i[0] == 'py_call' and str(i[1])=='arctan':
            a=stack.pop(-1)
            detail.append(('mul', a, a))
            detail.append(('add', 1, a*a))
            detail.append(('atan', a))
            stackcomp.append(a*a)
            stackcomp.append(1+a*a)
            stackcomp.append(arctan(a))
            stack.append(arctan(a))

        elif i[0] == 'py_call' and str(i[1])=='arcsin':
            a=stack.pop(-1)
            detail.append(('mul', a, a))
            detail.append(('mul', -1, a*a))
            detail.append(('add', 1, -a*a))
            detail.append(('pow', 1- a*a, 0.5))
            detail.append(('asin', a))
            stackcomp.append(a*a)
            stackcomp.append(-a*a)
            stackcomp.append(1-a*a)
            stackcomp.append(sqrt(1-a*a))
            stackcomp.append(arcsin(a))
            stack.append(arcsin(a))

        elif i[0] == 'py_call' and str(i[1])=='arccos':
            a=stack.pop(-1)
            detail.append(('mul', a, a))
            detail.append(('mul', -1, a*a))
            detail.append(('add', 1, -a*a))
            detail.append(('pow', 1- a*a, 0.5))
            detail.append(('mul', -1, sqrt(1-a*a)))
            detail.append(('acos', a))
            stackcomp.append(a*a)
            stackcomp.append(-a*a)
            stackcomp.append(1-a*a)
            stackcomp.append(sqrt(1-a*a))
            stackcomp.append(-sqrt(1-a*a))
            stackcomp.append(arccos(a))
            stack.append(arccos(a))

        elif i[0] == 'py_call' and 'sqrt' in str(i[1]):
            a=stack.pop(-1)
            detail.append(('pow', a, 0.5))
            stackcomp.append(sqrt(a))
            stack.append(sqrt(a))


        elif i == 'neg':
            a = stack.pop(-1)
            detail.append(('mul', -1, a))
            stack.append(-a)
            stackcomp.append(-a)

    return stackcomp,detail
Пример #52
0
def _geodesic_between_two_points_d(x1,y1,x2,y2,z0=I):
    r""" Geodesic path between two points represented in the unit disc
         by the map w = (z-I)/(z+I)
    INPUTS:
    - ''(x1,y1)'' -- starting point (0<y1<=infinity)
    - ''(x2,y2)'' -- ending point   (0<y2<=infinity)
    - ''z0''  -- (default I) the point in the upper corresponding
                 to the point 0 in the disc. I.e. the transform is
                 w -> (z-I)/(z+I)
    OUTPUT:
    - ''ca'' -- a polygonal approximation of a circular arc centered
    at c and radius r, starting at t0 and ending at t1

    
    EXAMPLES::

        sage: l=_geodesic_between_two_points_d(0.1,0.2,0.0,0.5)
    
    """
    pi=RR.pi()
    from sage.plot.plot import line
    from sage.functions.trig import (cos,sin)    
    # First compute the points
    if(y1<0  or y2<0 ):
        raise ValueError,"Need points in the upper half-plane! Got y1=%s, y2=%s" %(y1,y2)
    if(y1==infinity):
        P1=CC(1 )
    else:
        P1=CC((x1+I*y1-z0)/(x1+I*y1-z0.conjugate()))
    if(y2==infinity):
        P2=CC(1 )
    else:
        P2=CC((x2+I*y2-z0)/(x2+I*y2-z0.conjugate()))
        # First find the endpoints of the completed geodesic in D
    if(x1==x2):
        a=CC((x1-z0)/(x1-z0.conjugate()))
        b=CC(1 )
    else:
        c=RR(y1**2 -y2**2 +x1**2 -x2**2 )/RR(2 *(x1-x2))
        r=RR(sqrt(y1**2 +(x1-c)**2 ))
        a=c-r
        b=c+r
        a=CC((a-z0)/(a-z0.conjugate()))
        b=CC((b-z0)/(b-z0.conjugate()))
    if( abs(a+b) < 1E-10 ): # On a diagonal
        return line([[P1.real(),P1.imag()],[P2.real(),P2.imag()]])
    th_a=a.argument()
    th_b=b.argument()
    # Compute the center of the circle in the disc model
    if( min(abs(b-1 ),abs(b+1 ))< 1E-10  and  min(abs(a-1 ),abs(a+1 ))>1E-10 ):
        c=b+I*(1 -b*cos(th_a))/sin(th_a)
    elif( min(abs(b-1 ),abs(b+1 ))> 1E-10  and  min(abs(a-1 ),abs(a+1 ))<1E-10 ):
        c=a+I*(1 -a*cos(th_b))/RR(sin(th_b))
    else:
        cx=(sin(th_b)-sin(th_a))/sin(th_b-th_a)
        c=cx+I*(1 -cx*cos(th_b))/RR(sin(th_b))
    # First find the endpoints of the completed geodesic
    r=abs(c-a)
    t1=CC(P1-c).argument()
    t2=CC(P2-c).argument()
    #print "t1,t2=",t1,t2
    return _circ_arc(t1,t2,c,r)
Пример #53
0
 def f(t):
     return (radius_arc * cos(t) + center[0],
             radius_arc * sin(t) + center[1])
Пример #54
0
 def f(t):
     return exp(I * ((cos(t) + I * sin(t)) *
                     arc_radius + arc_center)) * radius
    radius=norm(first_vector)
    if norm(second_vector)!=radius:
        raise ValueError("Ellipse not implemented")
    first_unit_vector=first_vector/radius
    second_unit_vector=second_vector/radius
    normal_vector=second_vector-(second_vector*first_unit_vector)*first_unit_vector
    if norm(normal_vector)==0:
        print (first_point,second_point)
        return
    normal_unit_vector=normal_vector/norm(normal_vector)
    scalar_product=first_unit_vector*second_unit_vector
    if abs(scalar_product) == 1:
        raise ValueError("The points are alligned")
    angle=arccos(scalar_product)
    var('t')
    return parametric_plot3d(center+first_vector*cos(t)+radius*normal_unit_vector*sin(t),(0,angle),**kwds)
     

     
def _arc(p,q,s,**kwds):
    #rewrite this to use polar_plot and get points to do filled triangles
    from sage.misc.functional import det
    from sage.plot.line import line
    from sage.misc.functional import norm
    from sage.symbolic.all import pi
    from sage.plot.arc import arc
     
    p,q,s = map( lambda x: vector(x), [p,q,s])
     
    # to avoid running into division by 0 we set to be colinear vectors that are
    # almost colinear
Пример #56
0
def barycentric_projection_matrix(n, angle=0):
    r"""
    Returns a family of `n+1` vectors evenly spaced in a real vector space of dimension `n`

    Those vectors are of norm `1`, the scalar product between any two
    vector is `1/n`, thus the distance between two tips is constant.

    The family is built recursively and uniquely determined by the
    following property: the last vector is `(0,\dots,0,-1)`, and the
    projection of the first `n` vectors in dimension `n-1`, after
    appropriate rescaling to norm `1`, retrieves the family for `n-1`.

    OUTPUT:

    A matrix with `n+1` columns of height `n` with rational or
    symbolic coefficients.

    EXAMPLES:

    One vector in dimension `0`::

        sage: from sage.combinat.root_system.root_lattice_realizations import barycentric_projection_matrix
        sage: m = barycentric_projection_matrix(0); m
        []
        sage: matrix(QQ,0,1).nrows()
        0
        sage: matrix(QQ,0,1).ncols()
        1

    Two vectors in dimension 1::

        sage: barycentric_projection_matrix(1)
        [ 1 -1]

    Three vectors in dimension 2::

        sage: barycentric_projection_matrix(2)
        [ 1/2*sqrt(3) -1/2*sqrt(3)            0]
        [         1/2          1/2           -1]

    Four vectors in dimension 3::

        sage: m = barycentric_projection_matrix(3); m
        [ 1/3*sqrt(3)*sqrt(2) -1/3*sqrt(3)*sqrt(2)                    0                    0]
        [         1/3*sqrt(2)          1/3*sqrt(2)         -2/3*sqrt(2)                    0]
        [                 1/3                  1/3                  1/3                   -1]

    The columns give four vectors that sum up to zero::

        sage: sum(m.columns())
        (0, 0, 0)

    and have regular mutual angles::

        sage: m.transpose()*m
        [   1 -1/3 -1/3 -1/3]
        [-1/3    1 -1/3 -1/3]
        [-1/3 -1/3    1 -1/3]
        [-1/3 -1/3 -1/3    1]

    Here is a plot of them::

        sage: sum(arrow((0,0,0),x) for x in m.columns())

    For 2D drawings of root systems, it is desirable to rotate the
    result to match with the usual conventions::

        sage: barycentric_projection_matrix(2, angle=2*pi/3)
        [         1/2           -1          1/2]
        [ 1/2*sqrt(3)            0 -1/2*sqrt(3)]

    TESTS::

        sage: for n in range(1, 7):
        ...       m = barycentric_projection_matrix(n)
        ...       assert sum(m.columns()).is_zero()
        ...       assert matrix(QQ, n+1,n+1, lambda i,j: 1 if i==j else -1/n) == m.transpose()*m

    """
    from sage.matrix.constructor import matrix
    from sage.functions.other import sqrt
    n = ZZ(n)
    if n == 0:
        return matrix(QQ, 0, 1)
    a = 1/n
    b = sqrt(1-a**2)
    result = b * barycentric_projection_matrix(n-1)
    result = result.augment(vector([0]*(n-1)))
    result = result.stack(matrix([[a]*n+[-1]]))
    assert sum(result.columns()).is_zero()
    if angle and n == 2:
        from sage.functions.trig import sin
        from sage.functions.trig import cos
        rotation = matrix([[sin(angle), cos(angle)],[-cos(angle), sin(angle)]])
        result = rotation * result
    result.set_immutable()
    return result