示例#1
0
def get_variables(n):
    if n == 0:
        return []
    if n == 1:
        return [var('t')]
    names = ['t' + str(i) for i in xrange(n)]
    return list(var(names))
示例#2
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)
示例#3
0
def spin_polynomial(part, weight, length):
    """
    Returns the spin polynomial associated to ``part``, ``weight``, and
    ``length``.

    EXAMPLES::

        sage: from sage.combinat.ribbon_tableau import spin_polynomial
        sage: spin_polynomial([6,6,6],[4,2],3)
        t^6 + t^5 + 2*t^4 + t^3 + t^2
        sage: spin_polynomial([6,6,6],[4,1,1],3)
        t^6 + 2*t^5 + 3*t^4 + 2*t^3 + t^2
        sage: spin_polynomial([3,3,3,2,1], [2,2], 3)
        t^(7/2) + t^(5/2)
        sage: spin_polynomial([3,3,3,2,1], [2,1,1], 3)
        2*t^(7/2) + 2*t^(5/2) + t^(3/2)
        sage: spin_polynomial([3,3,3,2,1], [1,1,1,1], 3)
        3*t^(7/2) + 5*t^(5/2) + 3*t^(3/2) + sqrt(t)
        sage: spin_polynomial([5,4,3,2,1,1,1], [2,2,1], 3)
        2*t^(9/2) + 6*t^(7/2) + 2*t^(5/2)
        sage: spin_polynomial([[6]*6, [3,3]], [4,4,2], 3)
        3*t^9 + 5*t^8 + 9*t^7 + 6*t^6 + 3*t^5
    """
    from sage.symbolic.ring import var
    sp = spin_polynomial_square(part,weight,length)
    t = var('t')
    c = sp.coeffs()
    return sum([c[i]*t**(QQ(i)/2) for i in range(len(c))])
示例#4
0
    def Enneper(name="Enneper's surface"):
        r"""
        Return Enneper's surface, with parametrization

        .. MATH::

            \begin{aligned}
              x(u, v) & = u(1 - u^2/3 + v^2)/3; \\
              y(u, v) & = -v(1 - v^2/3 + u^2)/3; \\
              z(u, v) & = (u^2 - v^2)/3.
            \end{aligned}

        INPUT:

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

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

        EXAMPLES::

            sage: enn = surfaces.Enneper(); enn
            Parametrized surface ('Enneper's surface') with equation (-1/9*(u^2 - 3*v^2 - 3)*u, -1/9*(3*u^2 - v^2 + 3)*v, 1/3*u^2 - 1/3*v^2)
            sage: enn.plot()
            Graphics3d Object
        """
        u, v = var('u, v')
        enneper_eq = [
            u * (1 - u**2 / 3 + v**2) / 3, -v * (1 - v**2 / 3 + u**2) / 3,
            (u**2 - v**2) / 3
        ]
        coords = ((u, -3, 3), (v, -3, 3))
        return ParametrizedSurface3D(enneper_eq, coords, name)
示例#5
0
def spin_polynomial(part, weight, length):
    """
    Returns the spin polynomial associated to part, weight, and
    length.
    
    EXAMPLES::
    
        sage: from sage.combinat.ribbon_tableau import spin_polynomial
        sage: spin_polynomial([6,6,6],[4,2],3)
        t^6 + t^5 + 2*t^4 + t^3 + t^2
        sage: spin_polynomial([6,6,6],[4,1,1],3)
        t^6 + 2*t^5 + 3*t^4 + 2*t^3 + t^2
        sage: spin_polynomial([3,3,3,2,1], [2,2], 3)
        t^(7/2) + t^(5/2)
        sage: spin_polynomial([3,3,3,2,1], [2,1,1], 3)
        2*t^(7/2) + 2*t^(5/2) + t^(3/2)
        sage: spin_polynomial([3,3,3,2,1], [1,1,1,1], 3)
        3*t^(7/2) + 5*t^(5/2) + 3*t^(3/2) + sqrt(t)
        sage: spin_polynomial([5,4,3,2,1,1,1], [2,2,1], 3)
        2*t^(9/2) + 6*t^(7/2) + 2*t^(5/2)
        sage: spin_polynomial([[6]*6, [3,3]], [4,4,2], 3)
        3*t^9 + 5*t^8 + 9*t^7 + 6*t^6 + 3*t^5
    """
    from sage.symbolic.ring import var
    sp = spin_polynomial_square(part, weight, length)
    t = var('t')
    c = sp.coeffs()
    return sum([c[i] * t**(QQ(i) / 2) for i in range(len(c))])
示例#6
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)
示例#7
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)
示例#8
0
    def MonkeySaddle(name="Monkey saddle"):
        r"""
        Returns a monkey saddle surface, with equation

        .. MATH::

            z = x^3 - 3xy^2.

        INPUT:

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

        EXAMPLES::

            sage: saddle = surfaces.MonkeySaddle(); saddle
            Parametrized surface ('Monkey saddle') with equation (u, v, u^3 - 3*u*v^2)
            sage: saddle.plot()
            Graphics3d Object

        """

        u, v = var("u, v")
        monkey_eq = [u, v, u ** 3 - 3 * u * v ** 2]
        coords = ((u, -2, 2), (v, -2, 2))

        return ParametrizedSurface3D(monkey_eq, coords, name)
示例#9
0
    def Enneper(name="Enneper's surface"):
        r"""
        Returns Enneper's surface, with parametrization

        .. MATH::

            \begin{aligned}
              x(u, v) & = u(1 - u^2/3 + v^2)/3; \\
              y(u, v) & = -v(1 - v^2/3 + u^2)/3; \\
              z(u, v) & = (u^2 - v^2)/3.
            \end{aligned}

        INPUT:

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

        EXAMPLES::

            sage: enn = surfaces.Enneper(); enn
            Parametrized surface ('Enneper's surface') with equation (-1/9*(u^2 - 3*v^2 - 3)*u, -1/9*(3*u^2 - v^2 + 3)*v, 1/3*u^2 - 1/3*v^2)
            sage: enn.plot()
            Graphics3d Object

        """

        u, v = var("u, v")
        enneper_eq = [u * (1 - u ** 2 / 3 + v ** 2) / 3, -v * (1 - v ** 2 / 3 + u ** 2) / 3, (u ** 2 - v ** 2) / 3]
        coords = ((u, -3, 3), (v, -3, 3))

        return ParametrizedSurface3D(enneper_eq, coords, name)
示例#10
0
    def WhitneyUmbrella(name="Whitney's umbrella"):
        r"""
        Return Whitney's umbrella, with parametric representation

        .. MATH::

            x(u, v) = uv, \quad y(u, v) = u, \quad z(u, v) = v^2.

        INPUT:

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

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

        EXAMPLES::

            sage: whitney = surfaces.WhitneyUmbrella(); whitney
            Parametrized surface ('Whitney's umbrella') with equation (u*v, u, v^2)
            sage: whitney.plot()
            Graphics3d Object
        """
        u, v = var('u, v')
        whitney_eq = [u * v, u, v**2]
        coords = ((u, -1, 1), (v, -1, 1))
        return ParametrizedSurface3D(whitney_eq, coords, name)
示例#11
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)
示例#12
0
    def MonkeySaddle(name="Monkey saddle"):
        r"""
        Return a monkey saddle surface, with equation

        .. MATH::

            z = x^3 - 3xy^2.

        INPUT:

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

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

        EXAMPLES::

            sage: saddle = surfaces.MonkeySaddle(); saddle
            Parametrized surface ('Monkey saddle') with equation (u, v, u^3 - 3*u*v^2)
            sage: saddle.plot()
            Graphics3d Object
        """
        u, v = var('u, v')
        monkey_eq = [u, v, u**3 - 3 * u * v**2]
        coords = ((u, -2, 2), (v, -2, 2))

        return ParametrizedSurface3D(monkey_eq, coords, name)
示例#13
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)
示例#14
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)
示例#15
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)
示例#16
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)
    def __init__(self, coordinate_patch = None):
        """
        Construct the algebra of differential forms on a given coordinate patch.
        See ``DifferentialForms`` for details.

        INPUT::

        - ``coordinate_patch`` -- Coordinate patch where the algebra lives.
        If no coordinate patch is given, a default coordinate patch with
        coordinates (x, y, z) is used.

        EXAMPLES::

            sage: p, q = var('p, q')
            sage: U = CoordinatePatch((p, q)); U
            Open subset of R^2 with coordinates p, q
            sage: F = DifferentialForms(U); F
            Algebra of differential forms in the variables p, q

        """

        from sage.categories.graded_algebras_with_basis \
            import GradedAlgebrasWithBasis
        from sage.structure.parent_gens import ParentWithGens

        if not coordinate_patch:
            x, y, z = var('x, y, z')
            coordinate_patch = CoordinatePatch((x, y, z))

        if not isinstance(coordinate_patch, CoordinatePatch):
            raise TypeError("%s not a valid Coordinate Patch" % coordinate_patch)
        self._patch = coordinate_patch

        ParentWithGens.__init__(self, SR, \
                                category = GradedAlgebrasWithBasis(SR))
示例#18
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)
示例#19
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()
            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)
示例#20
0
    def WhitneyUmbrella(name="Whitney's umbrella"):
        r"""
        Returns Whitney's umbrella, with parametric representation

        .. MATH::

            x(u, v) = uv, \quad y(u, v) = u, \quad z(u, v) = v^2.

        INPUT:

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

        EXAMPLES::

            sage: whitney = surfaces.WhitneyUmbrella(); whitney
            Parametrized surface ('Whitney's umbrella') with equation (u*v, u, v^2)
            sage: whitney.plot()
            Graphics3d Object

        """

        u, v = var("u, v")
        whitney_eq = [u * v, u, v ** 2]
        coords = ((u, -1, 1), (v, -1, 1))

        return ParametrizedSurface3D(whitney_eq, coords, name)
示例#21
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)
示例#22
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)
示例#23
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)
示例#24
0
def _real_or_imaginary_part_of_power_of_complex_number(n, start):
    """
    Let z = x + y * I.
    If start = 0, return Re(z^n). If start = 1, return Im(z^n).
    The result is a sage symbolic expression in x and y with rational
    coefficients.
    """

    # By binomial theorem, we have
    #
    #               n       n        n       n    n-i    i
    #   (x + y * I)   = sum       (     ) * I  * x    * y
    #                     i = 0      i
    #
    # The real/imaginary part consists of all even/odd terms in the sum:
    return sum([
        binomial(n, i) * (-1) ** (i/2) * var('x') ** (n - i) * var('y') ** i
        for i in range(start, n + 1, 2)])
示例#25
0
    def Paraboloid(a=1, b=1, c=1, elliptic=True, name=None):
        r"""
        Returns a paraboloid with equation

        .. MATH::

            \frac{z}{c} = \pm \frac{x^2}{a^2} + \frac{y^2}{b^2}

        When the plus sign is selected, the paraboloid is elliptic. Otherwise
        the surface is a hyperbolic paraboloid.

        INPUT:

        - ``a``, ``b``, ``c`` -- Surface parameters.

        - ``elliptic`` (default: True) -- whether to create an elliptic or
          hyperbolic paraboloid.

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

        EXAMPLES::

            sage: epar = surfaces.Paraboloid(1, 3, 2); epar
            Parametrized surface ('Elliptic paraboloid') with equation (u, v, 2*u^2 + 2/9*v^2)
            sage: epar.plot()
            Graphics3d Object

            sage: hpar = surfaces.Paraboloid(2, 3, 1, elliptic=False); hpar
            Parametrized surface ('Hyperbolic paraboloid') with equation (u, v, -1/4*u^2 + 1/9*v^2)
            sage: hpar.plot()
            Graphics3d Object

        """

        u, v = var("u, v")
        x = u
        y = v
        if elliptic:
            z = c * (v ** 2 / b ** 2 + u ** 2 / a ** 2)
        else:
            z = c * (v ** 2 / b ** 2 - u ** 2 / a ** 2)
        paraboloid_eq = [x, y, z]
        coords = ((u, -3, 3), (v, -3, 3))

        if name is None:
            if elliptic:
                name = "Elliptic paraboloid"
            else:
                name = "Hyperbolic paraboloid"

        return ParametrizedSurface3D(paraboloid_eq, coords, name)
示例#26
0
    def Paraboloid(a=1, b=1, c=1, elliptic=True, name=None):
        r"""
        Return a paraboloid with equation

        .. MATH::

            \frac{z}{c} = \pm \frac{x^2}{a^2} + \frac{y^2}{b^2}

        When the plus sign is selected, the paraboloid is elliptic. Otherwise
        the surface is a hyperbolic paraboloid.

        INPUT:

        - ``a``, ``b``, ``c`` -- Surface parameters.

        - ``elliptic`` (default: True) -- whether to create an elliptic or
          hyperbolic paraboloid.

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

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

        EXAMPLES::

            sage: epar = surfaces.Paraboloid(1, 3, 2); epar
            Parametrized surface ('Elliptic paraboloid') with equation (u, v, 2*u^2 + 2/9*v^2)
            sage: epar.plot()
            Graphics3d Object

            sage: hpar = surfaces.Paraboloid(2, 3, 1, elliptic=False); hpar
            Parametrized surface ('Hyperbolic paraboloid') with equation (u, v, -1/4*u^2 + 1/9*v^2)
            sage: hpar.plot()
            Graphics3d Object
        """
        u, v = var('u, v')
        x = u
        y = v
        if elliptic:
            z = c * (v**2 / b**2 + u**2 / a**2)
        else:
            z = c * (v**2 / b**2 - u**2 / a**2)
        paraboloid_eq = [x, y, z]
        coords = ((u, -3, 3), (v, -3, 3))

        if name is None:
            if elliptic:
                name = "Elliptic paraboloid"
            else:
                name = "Hyperbolic paraboloid"

        return ParametrizedSurface3D(paraboloid_eq, coords, name)
示例#27
0
    def __init__(self, L, name, **kwds):
        r"""
        Initialize ``self``.

        TESTS::

            sage: L = lie_algebras.Heisenberg(QQ, 2)
            sage: G = L.lie_group()
            sage: TestSuite(G).run()
        """
        required_cat = LieAlgebras(L.base_ring()).FiniteDimensional()
        required_cat = required_cat.WithBasis().Nilpotent()
        if L not in required_cat:
            raise TypeError("L needs to be a finite dimensional nilpotent "
                            "Lie algebra with basis")
        self._lie_algebra = L

        R = L.base_ring()
        category = kwds.pop('category', None)
        category = LieGroups(R).or_subcategory(category)
        if isinstance(R, RealField_class):
            structure = RealDifferentialStructure()
        else:
            structure = DifferentialStructure()

        DifferentiableManifold.__init__(self,
                                        L.dimension(),
                                        name,
                                        R,
                                        structure,
                                        category=category)

        # initialize exponential coordinates of the first kind
        basis_strs = [str(X) for X in L.basis()]
        split = list(zip(*[s.split('_') for s in basis_strs]))
        if len(split) == 2 and all(sk == split[0][0] for sk in split[0]):
            self._var_indexing = split[1]
        else:
            self._var_indexing = [str(k) for k in range(L.dimension())]
        variables = ' '.join('x_%s' % k for k in self._var_indexing)
        self._Exp1 = self.chart(variables)

        # compute a symbolic formula for the group law
        L_SR = _symbolic_lie_algebra_copy(L)
        n = L.dimension()
        a, b = (tuple(var('%s_%d' % (s, j)) for j in range(n))
                for s in ['a', 'b'])
        self._group_law_vars = (a, b)
        bch = L_SR.bch(L_SR.from_vector(a), L_SR.from_vector(b), L.step())
        self._group_law = vector(SR, (zk.expand() for zk in bch.to_vector()))
 def __init__(self,divisor):
   self.divisor = divisor
   self.poly_ring = divisor.parent()
   hw = homogenous_wieghts(divisor)
   self.wieghts = hw[1:]
   self.degree = hw[0]
   #Setup patch for differential form
   var_names = [ g.__repr__() for g in self.poly_ring.gens()]
   self.form_vars = var(",".join(var_names))
   self.form_patch = CoordinatePatch(self.form_vars)
   self.form_space = DifferentialForms(self.form_patch)
   #compute the generators of the logarithmic p-forms
   self._p_modules = {} # modules of logarithmic differential p-forms
   self._p_gens = {} # the generators of the module of logarithmic differential p-forms
   self._p_zero_part_basis = {}
示例#29
0
    def __init__(self, coordinate_patch=None):
        """
        Construct the algebra of differential forms on a given coordinate patch.

        See ``DifferentialForms`` for details.

        INPUT:

        - ``coordinate_patch`` -- Coordinate patch where the algebra lives.

        If no coordinate patch is given, a default coordinate patch with
        coordinates (x, y, z) is used.

        EXAMPLES::

            sage: p, q = var('p, q')
            sage: U = CoordinatePatch((p, q)); U
            doctest:...: DeprecationWarning: Use Manifold instead.
            See http://trac.sagemath.org/24444 for details.
            Open subset of R^2 with coordinates p, q
            sage: F = DifferentialForms(U); F
            doctest:...:  DeprecationWarning: For the set of differential forms of
             degree p, use U.diff_form_module(p), where U is the base manifold
             (type U.diff_form_module? for details).
            See http://trac.sagemath.org/24444 for details.
            Algebra of differential forms in the variables p, q
        """
        from sage.categories.graded_algebras_with_basis \
            import GradedAlgebrasWithBasis
        from sage.structure.parent_gens import ParentWithGens
        from sage.misc.superseded import deprecation
        deprecation(
            24444, 'For the set of differential forms of degree p, ' +
            'use U.diff_form_module(p), where U is the base ' +
            'manifold (type U.diff_form_module? for details).')

        if not coordinate_patch:
            x, y, z = var('x, y, z')
            coordinate_patch = CoordinatePatch((x, y, z))

        if not isinstance(coordinate_patch, CoordinatePatch):
            raise TypeError("%s not a valid Coordinate Patch" %
                            coordinate_patch)
        self._patch = coordinate_patch

        ParentWithGens.__init__(self, SR, \
                                category = GradedAlgebrasWithBasis(SR))
示例#30
0
    def __init__(self, L, name, **kwds):
        r"""
        Initialize ``self``.

        TESTS::

            sage: L = lie_algebras.Heisenberg(QQ, 2)
            sage: G = L.lie_group()
            sage: TestSuite(G).run()
        """
        required_cat = LieAlgebras(L.base_ring()).FiniteDimensional()
        required_cat = required_cat.WithBasis().Nilpotent()
        if L not in required_cat:
            raise TypeError("L needs to be a finite dimensional nilpotent "
                            "Lie algebra with basis")
        self._lie_algebra = L

        R = L.base_ring()
        category = kwds.pop('category', None)
        category = LieGroups(R).or_subcategory(category)
        if isinstance(R, RealField_class):
            structure = RealDifferentialStructure()
        else:
            structure = DifferentialStructure()

        DifferentiableManifold.__init__(self, L.dimension(), name, R,
                                        structure, category=category)

        # initialize exponential coordinates of the first kind
        basis_strs = [str(X) for X in L.basis()]
        split = list(zip(*[s.split('_') for s in basis_strs]))
        if len(split) == 2 and all(sk == split[0][0] for sk in split[0]):
            self._var_indexing = split[1]
        else:
            self._var_indexing = [str(k) for k in range(L.dimension())]
        variables = ' '.join('x_%s' % k for k in self._var_indexing)
        self._Exp1 = self.chart(variables)

        # compute a symbolic formula for the group law
        L_SR = _symbolic_lie_algebra_copy(L)
        n = L.dimension()
        a, b = (tuple(var('%s_%d' % (s, j)) for j in range(n))
                for s in ['a', 'b'])
        self._group_law_vars = (a, b)
        bch = L_SR.bch(L_SR.from_vector(a), L_SR.from_vector(b), L.step())
        self._group_law = vector(SR, (zk.expand() for zk in bch.to_vector()))
示例#31
0
    def __init__(self, coordinate_patch = None):
        """
        Construct the algebra of differential forms on a given coordinate patch.

        See ``DifferentialForms`` for details.

        INPUT:

        - ``coordinate_patch`` -- Coordinate patch where the algebra lives.

        If no coordinate patch is given, a default coordinate patch with
        coordinates (x, y, z) is used.

        EXAMPLES::

            sage: p, q = var('p, q')
            sage: U = CoordinatePatch((p, q)); U
            doctest:...: DeprecationWarning: Use Manifold instead.
            See http://trac.sagemath.org/24444 for details.
            Open subset of R^2 with coordinates p, q
            sage: F = DifferentialForms(U); F
            doctest:...:  DeprecationWarning: For the set of differential forms of
             degree p, use U.diff_form_module(p), where U is the base manifold
             (type U.diff_form_module? for details).
            See http://trac.sagemath.org/24444 for details.
            Algebra of differential forms in the variables p, q
        """
        from sage.categories.graded_algebras_with_basis \
            import GradedAlgebrasWithBasis
        from sage.structure.parent_gens import ParentWithGens
        from sage.misc.superseded import deprecation
        deprecation(24444, 'For the set of differential forms of degree p, ' +
                    'use U.diff_form_module(p), where U is the base ' +
                    'manifold (type U.diff_form_module? for details).')

        if not coordinate_patch:
            x, y, z = var('x, y, z')
            coordinate_patch = CoordinatePatch((x, y, z))

        if not isinstance(coordinate_patch, CoordinatePatch):
            raise TypeError("%s not a valid Coordinate Patch" % coordinate_patch)
        self._patch = coordinate_patch

        ParentWithGens.__init__(self, SR, \
                                category = GradedAlgebrasWithBasis(SR))
示例#32
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)
示例#33
0
def fixed_charpoly(M, variables):
    """
    Calcualate the characterictic polynomials of a matrix with entries
    in a group ring.

    The problem is that Sage doesn't do a good job at calculating
    characteristic polynomials of matrices over Symbolic Ring in
    certain cases. To overcome this, we create a new matrix over a
    Polynomial Ring where inverses of the variables are replaced with
    new variable, calculate the charpoly, then substitute back.

    INPUT:

    - ``M`` -- a square matrix over Symbolic Ring

    - ``variables`` -- the list of variables appearing in the entries
      of ``M``

    OUTPUT:

    the characterictic polynomial of ``M``

    """
    from sage.rings.polynomial.polynomial_ring_constructor import \
    PolynomialRing
    from sage.rings.integer_ring import ZZ
    sub_vars = {v : var(str(v) + 'inv') for v in variables}
    ring = PolynomialRing(ZZ, variables + sub_vars.values()) \
           if len(variables) > 0 else ZZ
    new_M = matrix(ring, M.nrows(), M.ncols())
    for i in xrange(M.nrows()):
        for j in xrange(M.ncols()):
            exp = M[i,j]
            a = exp.numerator()
            b = exp.denominator()
            new_M[i,j] = a * b.subs(sub_vars)
    poly = new_M.charpoly('u')
    back_sub = {str(sub_vars[v]) : 1/v for v in sub_vars}
    poly = poly.subs(**back_sub)
    return poly
示例#34
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)
示例#35
0
    def __call__(self, *args):
        """
        EXAMPLES::

            sage: from sage.symbolic.operators import FDerivativeOperator
            sage: x,y = var('x,y')
            sage: f = function('foo')
            sage: op = FDerivativeOperator(f, [0,1])
            sage: op(x,y)
            D[0, 1](foo)(x, y)
            sage: op(x,x^2)
            D[0, 1](foo)(x, x^2)

        TESTS:

        We should be able to operate on functions evaluated at a
        point, not just a symbolic variable, :trac:`12796`::

           sage: from sage.symbolic.operators import FDerivativeOperator
           sage: f = function('f')
           sage: op = FDerivativeOperator(f, [0])
           sage: op(1)
           D[0](f)(1)

        """
        if (not all(is_SymbolicVariable(x) for x in args) or
                len(args) != len(set(args))):
            # An evaluated derivative of the form f'(1) is not a
            # symbolic variable, yet we would like to treat it
            # like one. So, we replace the argument `1` with a
            # temporary variable e.g. `t0` and then evaluate the
            # derivative f'(t0) symbolically at t0=1. See trac
            # #12796.
            temp_args=[var("t%s"%i) for i in range(len(args))]
            vars=[temp_args[i] for i in self._parameter_set]
            return self._f(*temp_args).diff(*vars).function(*temp_args)(*args)
        vars = [args[i] for i in self._parameter_set]
        return self._f(*args).diff(*vars)
示例#36
0
 def setUp(self):
     self.poly_ring = PolynomialRing(QQ, "x", 3)
     self.x = self.poly_ring.gens()[0]
     self.y = self.poly_ring.gens()[1]
     self.z = self.poly_ring.gens()[2]
     self.vars = var('x,y,z')
示例#37
0
文件: affine_ds.py 项目: yjjcc/sage
    def dynatomic_polynomial(self, period):
        r"""
        Compute the (affine) dynatomic polynomial of a dynamical system
        `f: \mathbb{A}^1 \to \mathbb{A}^1`.

        The dynatomic polynomial is the analog of the cyclotomic polynomial
        and its roots are the points of formal period `n`.

        ALGORITHM:

        Homogenize to a map `f: \mathbb{P}^1 \to \mathbb{P}^1` and compute
        the dynatomic polynomial there. Then, dehomogenize.

        INPUT:

        - ``period`` -- a positive integer or a list/tuple `[m,n]`,
          where `m` is the preperiod and `n` is the period

        OUTPUT:

        If possible, a single variable polynomial in the coordinate ring
        of the polynomial. Otherwise a fraction field element of the
        coordinate ring of the polynomial.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: f = DynamicalSystem_affine([x^2+y^2, y^2])
            sage: f.dynatomic_polynomial(2)
            Traceback (most recent call last):
            ...
            TypeError: does not make sense in dimension >1

        ::

            sage: A.<x> = AffineSpace(ZZ, 1)
            sage: f = DynamicalSystem_affine([(x^2+1)/x])
            sage: f.dynatomic_polynomial(4)
            2*x^12 + 18*x^10 + 57*x^8 + 79*x^6 + 48*x^4 + 12*x^2 + 1

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: f = DynamicalSystem_affine([(x^2+1)/(3*x)])
            sage: f.dynatomic_polynomial(3)
            13.0000000000000*x^6 + 117.000000000000*x^4 + 78.0000000000000*x^2 +
            1.00000000000000

        ::

            sage: A.<x> = AffineSpace(QQ, 1)
            sage: f = DynamicalSystem_affine([x^2-10/9])
            sage: f.dynatomic_polynomial([2, 1])
            531441*x^4 - 649539*x^2 - 524880

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: f = DynamicalSystem_affine([x^2+CC.0])
            sage: f.dynatomic_polynomial(2)
            x^2 + x + 1.00000000000000 + 1.00000000000000*I

        ::

            sage: K.<c> = FunctionField(QQ)
            sage: A.<x> = AffineSpace(K, 1)
            sage: f = DynamicalSystem_affine([x^2 + c])
            sage: f.dynatomic_polynomial(4)
            x^12 + 6*c*x^10 + x^9 + (15*c^2 + 3*c)*x^8 + 4*c*x^7 + (20*c^3 + 12*c^2 + 1)*x^6
            + (6*c^2 + 2*c)*x^5 + (15*c^4 + 18*c^3 + 3*c^2 + 4*c)*x^4 + (4*c^3 + 4*c^2 + 1)*x^3
            + (6*c^5 + 12*c^4 + 6*c^3 + 5*c^2 + c)*x^2 + (c^4 + 2*c^3 + c^2 + 2*c)*x
            + c^6 + 3*c^5 + 3*c^4 + 3*c^3 + 2*c^2 + 1

        ::

            sage: A.<z> = AffineSpace(QQ, 1)
            sage: f = DynamicalSystem_affine([z^2+3/z+1/7])
            sage: f.dynatomic_polynomial(1).parent()
            Multivariate Polynomial Ring in z over Rational Field

        ::

            sage: R.<c> = QQ[]
            sage: A.<z> = AffineSpace(R,1)
            sage: f = DynamicalSystem_affine([z^2 + c])
            sage: f.dynatomic_polynomial([1,1])
            z^2 + z + c

        ::

            sage: A.<x> = AffineSpace(CC,1)
            sage: F = DynamicalSystem_affine([1/2*x^2 + CC(sqrt(3))])
            sage: F.dynatomic_polynomial([1,1])
            (0.125000000000000*x^4 + 0.366025403784439*x^2 + 1.50000000000000)/(0.500000000000000*x^2 - x + 1.73205080756888)

        TESTS::

            sage: R.<c> = QQ[]
            sage: Pc.<x,y> = ProjectiveSpace(R, 1)
            sage: G = DynamicalSystem_projective([(1/2*c + 1/2)*x^2 + (-2*c)*x*y + 2*c*y^2 , \
                  (1/4*c + 1/2)*x^2 + (-c - 1)*x*y + (c + 1)*y^2])
            sage: G.dehomogenize(1).dynatomic_polynomial(2)
            (1/4*c + 1/4)*x^2 + (-c - 1/2)*x + c + 1
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if not is_AffineSpace(self.domain()):
            raise NotImplementedError("not implemented for subschemes")
        if self.domain().dimension_relative() > 1:
            raise TypeError("does not make sense in dimension >1")
        G = self.homogenize(1)
        F = G.dynatomic_polynomial(period)
        T = G.domain().coordinate_ring()
        S = self.domain().coordinate_ring()
        if is_SymbolicExpressionRing(F.parent()):
            u = var(self.domain().coordinate_ring().variable_name())
            return F.subs({F.variables()[0]: u, F.variables()[1]: 1})
        elif T(F.denominator()).degree() == 0:
            R = F.parent()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F)
        else:
            R = F.numerator().parent()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F.numerator()) / phi(F.denominator())
示例#38
0
def field_containing_real_and_imaginary_part_of_number_field(number_field):
    """
    Given a Sage number field number_field with a complex embedding z, return
               (real_number_field, real_part, imag_part).

    The number field real_number_field is the smallest number field containing
    the real part and imaginary part of every element in number_field.

    real_part and imag_part are elements in real_number_field which comes with
    a real embedding such that under this embedding, we have
               z = real_part + imag_part * I.

        sage: from sage.rings.complex_field import ComplexField
        sage: CF = ComplexField()
        sage: x = var('x')
        sage: nf = NumberField(x**2 + 1, 'x', embedding = CF(1.0j))
        sage: field_containing_real_and_imaginary_part_of_number_field(nf)
        (Number Field in x with defining polynomial x with x = 0, 0, 1)

        sage: nf = NumberField(x**2 + 7, 'x', embedding = CF(2.64575j))
        sage: field_containing_real_and_imaginary_part_of_number_field(nf)
        (Number Field in x with defining polynomial x^2 - 7 with x = 2.645751311064591?, 0, x)

        sage: nf = NumberField(x**3 + x**2 + 23, 'x', embedding = CF(1.1096 + 2.4317j))
        sage: field_containing_real_and_imaginary_part_of_number_field(nf)
        (Number Field in x with defining polynomial x^6 + 2*x^5 + 2*x^4 - 113/2*x^3 - 229/4*x^2 - 115/4*x - 575/8 with x = 3.541338405550421?, -20/14377*x^5 + 382/14377*x^4 + 526/14377*x^3 + 1533/14377*x^2 - 18262/14377*x - 10902/14377, 20/14377*x^5 - 382/14377*x^4 - 526/14377*x^3 - 1533/14377*x^2 + 32639/14377*x + 10902/14377)
    """

    # Let p be the defining polynomial of the given number field.
    # Given the one complex equation p(z) = 0, translate it into two
    # real equations Re(p(x+y*I)) = 0, Im(p(x+y*I)) = 0.
    # equations are sage symbolic expressions in x and y.
    equations = [
        _real_or_imaginary_part_for_polynomial_in_complex_variable(
            number_field.defining_polynomial(), start) for start in [0, 1]
    ]

    # In _solve_two_equations, we implemented a method that can solve
    # a system of two polynomial equations in two variables x and y
    # provided that y is in the number field generated by x.
    # If we are lucky, this is the case.
    # If we are unlucky, the number field containing x and y is generated
    # by x' = x + k * y where k is some small natural number.

    # The k mentioned above. We start with 0 and increase until we
    # succeed.
    k = 0

    # The amount of extra precision beyond double precision we are working
    # with. We increase it if one of the above methods fails to find the right
    # factor of the above polynomials.
    extra_prec = 0

    # Initialize the intervals for x and y with double prescision intervals
    CIF = ComplexIntervalField()
    z_val = CIF(number_field.gen_embedding())
    x_val = z_val.real()
    y_val = z_val.imag()

    # Keep trying to find a k or increase precision until we succeed
    # Give up if k reaches 100 or we are at precision 16 times greater than
    # that of a double
    while k < 100 and extra_prec < 5:

        # Compute the interval for x'
        xprime_val = x_val + k * y_val

        # From the equations for x and y, get the equations for x' and y
        # where x' = x + k * y as abover
        equations_for_xprime = [
            eqn.substitute(x=var('x') - k * var('y')) for eqn in equations
        ]

        try:
            # Try to find a solution to the two equations
            solution = _solve_two_equations(equations_for_xprime[0],
                                            equations_for_xprime[1],
                                            xprime_val, y_val)

            if solution:
                # We succeeded. We have a solution for the equations in
                # x' and y, thus, we need to do x = x' - k * y
                real_number_field, y_expression = solution
                x_expression = real_number_field.gen() - k * y_expression
                return real_number_field, x_expression, y_expression
            else:
                # No solution found. This means that y is not in the
                # number field generated by x'. Try a higher k in the
                # next iteration
                k += 1

        except _IsolateFactorError:
            # We did not use enough precision. The given intervals for
            # x and y that are supposed to isolate a solution to the
            # system of two equations did not have enough precision to
            # succeed and give a unique answer.

            # Double the precision we will use from now on
            extra_prec += 1

            # Recompute the intervals for x and y with the new precision.
            CIF = ComplexIntervalField(53 * 2**extra_prec)
            z_val = CIF(number_field.gen_embedding())
            x_val = z_val.real()
            y_val = z_val.imag()

    # Give up
    return None
示例#39
0
    def dynatomic_polynomial(self, period):
        r"""
        Compute the (affine) dynatomic polynomial of a dynamical system
        `f: \mathbb{A}^1 \to \mathbb{A}^1`.

        The dynatomic polynomial is the analog of the cyclotomic polynomial
        and its roots are the points of formal period `n`.

        ALGORITHM:

        Homogenize to a map `f: \mathbb{P}^1 \to \mathbb{P}^1` and compute
        the dynatomic polynomial there. Then, dehomogenize.

        INPUT:

        - ``period`` -- a positive integer or a list/tuple `[m,n]`,
          where `m` is the preperiod and `n` is the period

        OUTPUT:

        If possible, a single variable polynomial in the coordinate ring
        of the polynomial. Otherwise a fraction field element of the
        coordinate ring of the polynomial.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: f = DynamicalSystem_affine([x^2+y^2, y^2])
            sage: f.dynatomic_polynomial(2)
            Traceback (most recent call last):
            ...
            TypeError: does not make sense in dimension >1

        ::

            sage: A.<x> = AffineSpace(ZZ, 1)
            sage: f = DynamicalSystem_affine([(x^2+1)/x])
            sage: f.dynatomic_polynomial(4)
            2*x^12 + 18*x^10 + 57*x^8 + 79*x^6 + 48*x^4 + 12*x^2 + 1

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: f = DynamicalSystem_affine([(x^2+1)/(3*x)])
            sage: f.dynatomic_polynomial(3)
            13.0000000000000*x^6 + 117.000000000000*x^4 + 78.0000000000000*x^2 +
            1.00000000000000

        ::

            sage: A.<x> = AffineSpace(QQ, 1)
            sage: f = DynamicalSystem_affine([x^2-10/9])
            sage: f.dynatomic_polynomial([2, 1])
            531441*x^4 - 649539*x^2 - 524880

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: f = DynamicalSystem_affine([x^2+CC.0])
            sage: f.dynatomic_polynomial(2)
            x^2 + x + 1.00000000000000 + 1.00000000000000*I

        ::

            sage: K.<c> = FunctionField(QQ)
            sage: A.<x> = AffineSpace(K, 1)
            sage: f = DynamicalSystem_affine([x^2 + c])
            sage: f.dynatomic_polynomial(4)
            x^12 + 6*c*x^10 + x^9 + (15*c^2 + 3*c)*x^8 + 4*c*x^7 + (20*c^3 + 12*c^2 + 1)*x^6
            + (6*c^2 + 2*c)*x^5 + (15*c^4 + 18*c^3 + 3*c^2 + 4*c)*x^4 + (4*c^3 + 4*c^2 + 1)*x^3
            + (6*c^5 + 12*c^4 + 6*c^3 + 5*c^2 + c)*x^2 + (c^4 + 2*c^3 + c^2 + 2*c)*x
            + c^6 + 3*c^5 + 3*c^4 + 3*c^3 + 2*c^2 + 1

        ::

            sage: A.<z> = AffineSpace(QQ, 1)
            sage: f = DynamicalSystem_affine([z^2+3/z+1/7])
            sage: f.dynatomic_polynomial(1).parent()
            Multivariate Polynomial Ring in z over Rational Field

        ::

            sage: R.<c> = QQ[]
            sage: A.<z> = AffineSpace(R,1)
            sage: f = DynamicalSystem_affine([z^2 + c])
            sage: f.dynatomic_polynomial([1,1])
            z^2 + z + c

        ::

            sage: A.<x> = AffineSpace(CC,1)
            sage: F = DynamicalSystem_affine([1/2*x^2 + CC(sqrt(3))])
            sage: F.dynatomic_polynomial([1,1])
            (0.125000000000000*x^4 + 0.366025403784439*x^2 + 1.50000000000000)/(0.500000000000000*x^2 - x + 1.73205080756888)
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if not is_AffineSpace(self.domain()):
            raise NotImplementedError("not implemented for subschemes")
        if self.domain().dimension_relative() > 1:
            raise TypeError("does not make sense in dimension >1")
        G = self.homogenize(1)
        F = G.dynatomic_polynomial(period)
        T = G.domain().coordinate_ring()
        S = self.domain().coordinate_ring()
        if is_SymbolicExpressionRing(F.parent()):
            u = var(self.domain().coordinate_ring().variable_name())
            return F.subs({F.variables()[0]:u,F.variables()[1]:1})
        elif T(F.denominator()).degree() == 0:
            R = F.parent()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F)
        else:
            R = F.numerator().parent()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F.numerator())/phi(F.denominator())
示例#40
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 var
    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=var('fi')
    else:
        phi=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)
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 var
    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 = var('fi')
    else:
        phi = 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)
示例#42
0
    def symbolic_velocities(self, left='D', right=None):
        r"""
        Return a list of symbolic variables ready to be used by the
        user as the derivatives of the coordinate functions with respect
        to a curve parameter (i.e. the velocities along the curve).
        It may actually serve to denote anything else than velocities,
        with a name including the coordinate functions.
        The choice of strings provided as 'left' and 'right' arguments
        is not entirely free since it must comply with Python
        prescriptions.

        INPUT:

        - ``left`` -- (default: ``D``) string to concatenate to the left
          of each coordinate functions of the chart
        - ``right`` -- (default: ``None``) string to concatenate to the
          right of each coordinate functions of the chart

        OUTPUT:

        - a list of symbolic expressions with the desired names

        EXAMPLES:

        Symbolic derivatives of the Cartesian coordinates of the
        3-dimensional Euclidean space::

            sage: R3 = Manifold(3, 'R3', start_index=1)
            sage: cart.<X,Y,Z> = R3.chart()
            sage: D = cart.symbolic_velocities(); D
            [DX, DY, DZ]
            sage: D = cart.symbolic_velocities(left='d', right="/dt"); D
            Traceback (most recent call last):
            ...
            ValueError: The name "dX/dt" is not a valid Python
             identifier.
            sage: D = cart.symbolic_velocities(left='d', right="_dt"); D
            [dX_dt, dY_dt, dZ_dt]
            sage: D = cart.symbolic_velocities(left='', right="'"); D
            Traceback (most recent call last):
            ...
            ValueError: The name "X'" is not a valid Python
             identifier.
            sage: D = cart.symbolic_velocities(left='', right="_dot"); D
            [X_dot, Y_dot, Z_dot]
            sage: R.<t> = RealLine()
            sage: canon_chart = R.default_chart()
            sage: D = canon_chart.symbolic_velocities() ; D
            [Dt]

        """

        from sage.symbolic.ring import var

        # The case len(self[:]) = 1 is treated apart due to the
        # following fact.
        # In the case of several coordinates, the argument of 'var' (as
        # implemented below after the case len(self[:]) = 1) is a list
        # of strings of the form ['Dx1', 'Dx2', ...] and not a unique
        # string of the form 'Dx1 Dx2 ...'.
        # Although 'var' is supposed to accept both syntaxes, the first
        # one causes an error when it contains only one argument, due to
        # line 784 of sage/symbolic/ring.pyx :
        # "return self.symbol(name, latex_name=formatted_latex_name, domain=domain)"
        # In this line, the first argument 'name' of 'symbol' is a list
        # and not a string if the argument of 'var' is a list of one
        # string (of the type ['Dt']), which causes error in 'symbol'.
        # This might be corrected.
        if len(self[:]) == 1:
            string_vel = left + format(self[:][0]) # will raise an error
            # in case left is not a string
            if right is not None:
                string_vel += right # will raise an error in case right
                # is not a string

            # If the argument of 'var' contains only one word, for
            # instance::
            # var('Dt')
            # then 'var' does not return a tuple containing one symbolic
            # expression, but the symbolic expression itself.
            # This is taken into account below in order to return a list
            # containing one symbolic expression.
            return [var(string_vel)]

        list_strings_velocities = [left + format(coord_func)
                                   for coord_func in self[:]] # will
        # raise an error in case left is not a string

        if right is not None:
            list_strings_velocities = [str_vel + right for str_vel
                                       in list_strings_velocities] # will
            # raise an error in case right is not a string

        return list(var(list_strings_velocities))
 def setUp(self):
   self.poly_ring = PolynomialRing(QQ,"x",3);
   self.x = self.poly_ring.gens()[0];
   self.y = self.poly_ring.gens()[1];
   self.z = self.poly_ring.gens()[2];
   self.vars = var('x,y,z')
示例#44
0
def sr_to_max(expr):
    r"""
    Convert a symbolic expression into a Maxima object.

    INPUT:

    - ``expr`` - symbolic expression

    OUTPUT: ECL object

    EXAMPLES::

        sage: from sage.interfaces.maxima_lib import sr_to_max
        sage: var('x')
        x
        sage: sr_to_max(x)
        <ECL: $X>
        sage: sr_to_max(cos(x))
        <ECL: ((%COS) $X)>
        sage: f = function('f',x)
        sage: sr_to_max(f.diff())
        <ECL: ((%DERIVATIVE) (($F) $X) $X 1)>

    TESTS:

    We should be able to convert derivatives evaluated at a point,
    :trac:`12796`::

        sage: from sage.interfaces.maxima_lib import sr_to_max, max_to_sr
        sage: f = function('f')
        sage: f_prime = f(x).diff(x)
        sage: max_to_sr(sr_to_max(f_prime(x = 1)))
        D[0](f)(1)

    """
    global sage_op_dict, max_op_dict
    global sage_sym_dict, max_sym_dict
    if isinstance(expr,list) or isinstance(expr,tuple):
        return EclObject(([mlist],[sr_to_max(e) for e in expr]))
    op = expr.operator()
    if op:
        # Stolen from sage.symbolic.expression_conversion
        # Should be defined in a function and then put in special_sage_to_max
        # For that, we should change the API of the functions there
        # (we need to have access to op, not only to expr.operands()
        if isinstance(op, FDerivativeOperator):
            from sage.symbolic.ring import is_SymbolicVariable
            args = expr.operands()
            if (not all(is_SymbolicVariable(v) for v in args) or
                len(args) != len(set(args))):
                # An evaluated derivative of the form f'(1) is not a
                # symbolic variable, yet we would like to treat it
                # like one. So, we replace the argument `1` with a
                # temporary variable e.g. `t0` and then evaluate the
                # derivative f'(t0) symbolically at t0=1. See trac
                # #12796.
                temp_args=[var("t%s"%i) for i in range(len(args))]
                f =sr_to_max(op.function()(*temp_args))
                params = op.parameter_set()
                deriv_max = [[mdiff],f]
                for i in set(params):
                    deriv_max.extend([sr_to_max(temp_args[i]), EclObject(params.count(i))])
                at_eval=sr_to_max([temp_args[i]==args[i] for i in range(len(args))])
                return EclObject([[max_at],deriv_max,at_eval])

            f = sr_to_max(op.function()(*args))
            params = op.parameter_set()
            deriv_max = []
            [deriv_max.extend([sr_to_max(args[i]), EclObject(params.count(i))]) for i in set(params)]
            l = [[mdiff],f]
            l.extend(deriv_max)
            return EclObject(l)
        elif (op in special_sage_to_max):
            return EclObject(special_sage_to_max[op](*[sr_to_max(o) for o in expr.operands()]))
        elif not (op in sage_op_dict):
            # Maxima does some simplifications automatically by default
            # so calling maxima(expr) can change the structure of expr
            #op_max=caar(maxima(expr).ecl())
            # This should be safe if we treated all special operators above
            op_max=maxima(op).ecl()
            sage_op_dict[op]=op_max
            max_op_dict[op_max]=op
        return EclObject(([sage_op_dict[op]],
                     [sr_to_max(o) for o in expr.operands()]))
    elif expr.is_symbol() or expr.is_constant():
        if not expr in sage_sym_dict:
            sym_max=maxima(expr).ecl()
            sage_sym_dict[expr]=sym_max
            max_sym_dict[sym_max]=expr
        return sage_sym_dict[expr]
    else:
        try:
            return pyobject_to_max(expr.pyobject())
        except TypeError:
            return maxima(expr).ecl()
示例#45
0
    def dynatomic_polynomial(self, period):
        r"""
        For a map `f:\mathbb{A}^1 \to \mathbb{A}^1` this function computes 
        the (affine) dynatomic polynomial.

        The dynatomic polynomial is the analog of the cyclotomic polynomial and its roots are the points
        of formal period `n`.

        ALGORITHM:

        Homogenize to a map `f:\mathbb{P}^1 \to \mathbb{P}^1` and compute the dynatomic polynomial there.
        Then, dehomogenize.

        INPUT:

        - ``period`` -- a positive integer or a list/tuple `[m,n]`,
          where `m` is the preperiod and `n` is the period.

        OUTPUT:

        - If possible, a single variable polynomial in the coordinate ring of the polynomial. \
          Otherwise a fraction field element of the coordinate ring of the polynomial.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: H = Hom(A, A)
            sage: f = H([x^2+y^2, y^2])
            sage: f.dynatomic_polynomial(2)
            Traceback (most recent call last):
            ...
            TypeError: does not make sense in dimension >1

        ::

            sage: A.<x> = AffineSpace(ZZ, 1)
            sage: H = Hom(A, A)
            sage: f = H([(x^2+1)/x])
            sage: f.dynatomic_polynomial(4)
            2*x^12 + 18*x^10 + 57*x^8 + 79*x^6 + 48*x^4 + 12*x^2 + 1

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: H = Hom(A, A)
            sage: f = H([(x^2+1)/(3*x)])
            sage: f.dynatomic_polynomial(3)
            13.0000000000000*x^6 + 117.000000000000*x^4 + 78.0000000000000*x^2 +
            1.00000000000000

        ::

            sage: A.<x> = AffineSpace(QQ, 1)
            sage: H = Hom(A, A)
            sage: f = H([x^2-10/9])
            sage: f.dynatomic_polynomial([2, 1])
            531441*x^4 - 649539*x^2 - 524880

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: H = Hom(A, A)
            sage: f = H([x^2+CC.0])
            sage: f.dynatomic_polynomial(2)
            x^2 + x + 1.00000000000000 + 1.00000000000000*I

        ::

            sage: K.<c> = FunctionField(QQ)
            sage: A.<x> = AffineSpace(K, 1)
            sage: H = Hom(A, A)
            sage: f = H([x^2 + c])
            sage: f.dynatomic_polynomial(4)
            x^12 + 6*c*x^10 + x^9 + (15*c^2 + 3*c)*x^8 + 4*c*x^7 + (20*c^3 + 12*c^2 + 1)*x^6
            + (6*c^2 + 2*c)*x^5 + (15*c^4 + 18*c^3 + 3*c^2 + 4*c)*x^4 + (4*c^3 + 4*c^2 + 1)*x^3
            + (6*c^5 + 12*c^4 + 6*c^3 + 5*c^2 + c)*x^2 + (c^4 + 2*c^3 + c^2 + 2*c)*x
            + c^6 + 3*c^5 + 3*c^4 + 3*c^3 + 2*c^2 + 1

        ::

            sage: A.<z> = AffineSpace(QQ, 1)
            sage: H = End(A)
            sage: f = H([z^2+3/z+1/7])
            sage: f.dynatomic_polynomial(1).parent()
            Multivariate Polynomial Ring in z over Rational Field

        ::

            sage: R.<c> = QQ[]
            sage: A.<z> = AffineSpace(R,1)
            sage: H = End(A)
            sage: f = H([z^2 + c])
            sage: f.dynatomic_polynomial([1,1])
            z^2 + z + c

        ::

            sage: A.<x> = AffineSpace(CC,1)
            sage: H = Hom(A,A)
            sage: F = H([1/2*x^2 + sqrt(3)])
            sage: F.dynatomic_polynomial([1,1])
            (2.00000000000000*x^4 + 5.85640646055102*x^2 + 24.0000000000000)/(x^2 + (-2.00000000000000)*x + 3.46410161513775)
        """
        if self.domain() != self.codomain():
            raise TypeError("must have same domain and codomain to iterate")
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.domain())==False:
            raise NotImplementedError("not implemented for subschemes")
        if self.domain().dimension_relative()>1:
            raise TypeError("does not make sense in dimension >1")
        G = self.homogenize(1)
        F = G.dynatomic_polynomial(period)
        T = G.domain().coordinate_ring()
        S = self.domain().coordinate_ring()
        if is_SymbolicExpressionRing(F.parent()):
            u = var(self.domain().coordinate_ring().variable_name())
            return F.subs({F.variables()[0]:u,F.variables()[1]:1})
        elif T(F.denominator()).degree() == 0:
            R = F.parent()
            phi = R.hom([S.gen(0), 1], S)
            return(phi(F))
        else:
            R = F.numerator().parent()
            phi = R.hom([S.gen(0), 1], S)
            return(phi(F.numerator())/phi(F.denominator()))