Exemplo n.º 1
0
    def _eval_(self, x):
        """
        EXAMPLES::

            sage: [dickman_rho(n) for n in [1..10]]
            [1.00000000000000, 0.306852819440055, 0.0486083882911316, 0.00491092564776083, 0.000354724700456040, 0.0000196496963539553, 8.74566995329392e-7, 3.23206930422610e-8, 1.01624828273784e-9, 2.77017183772596e-11]
            sage: dickman_rho(0)
            1.00000000000000
        """
        if not is_RealNumber(x):
            try:
                x = RR(x)
            except (TypeError, ValueError):
                return None  #PrimitiveFunction.__call__(self, SR(x))
        if x < 0:
            return x.parent()(0)
        elif x <= 1:
            return x.parent()(1)
        elif x <= 2:
            return 1 - x.log()
        n = x.floor()
        if self._cur_prec < x.parent().prec() or n not in self._f:
            self._cur_prec = rel_prec = x.parent().prec()
            # Go a bit beyond so we're not constantly re-computing.
            max = x.parent()(1.1) * x + 10
            abs_prec = (-self.approximate(max).log2() + rel_prec +
                        2 * max.log2()).ceil()
            self._f = {}
            if sys.getrecursionlimit() < max + 10:
                sys.setrecursionlimit(int(max) + 10)
            self._compute_power_series(max.floor(),
                                       abs_prec,
                                       cache_ring=x.parent())
        return self._f[n](2 * (x - n - x.parent()(0.5)))
Exemplo n.º 2
0
 def pyobject(self, ex, obj):
     from mathics.core import expression
     from mathics.core.expression import Number
     
     if obj is None:
         return expression.Symbol('Null')
     elif isinstance(obj, (list, tuple)) or is_Vector(obj):
         return expression.Expression('List', *(from_sage(item, self.subs) for item in obj))
     elif isinstance(obj, Constant):
         return expression.Symbol(obj._conversions.get('mathematica', obj._name))
     elif is_Integer(obj):
         return expression.Integer(str(obj))
     elif isinstance(obj, sage.Rational):
         rational = expression.Rational(str(obj))
         if rational.value.denom() == 1:
             return expression.Integer(rational.value.numer())
         else:
             return rational
     elif isinstance(obj, sage.RealDoubleElement) or is_RealNumber(obj):
         return expression.Real(str(obj))
     elif is_ComplexNumber(obj):
         real = Number.from_string(str(obj.real())).value
         imag = Number.from_string(str(obj.imag())).value
         return expression.Complex(real, imag)
     elif isinstance(obj, NumberFieldElement_quadratic):
         # TODO: this need not be a complex number, but we assume so!
         real = Number.from_string(str(obj.real())).value
         imag = Number.from_string(str(obj.imag())).value
         return expression.Complex(real, imag)
     else:
         return expression.from_python(obj)
Exemplo n.º 3
0
    def _eval_(self, x):
        """
        EXAMPLES::

            sage: [dickman_rho(n) for n in [1..10]]
            [1.00000000000000, 0.306852819440055, 0.0486083882911316, 0.00491092564776083, 0.000354724700456040, 0.0000196496963539553, 8.74566995329392e-7, 3.23206930422610e-8, 1.01624828273784e-9, 2.77017183772596e-11]
            sage: dickman_rho(0)
            1.00000000000000
        """
        if not is_RealNumber(x):
            try:
                x = RR(x)
            except (TypeError, ValueError):
                return None  # PrimitiveFunction.__call__(self, SR(x))
        if x < 0:
            return x.parent()(0)
        elif x <= 1:
            return x.parent()(1)
        elif x <= 2:
            return 1 - x.log()
        n = x.floor()
        if self._cur_prec < x.parent().prec() or n not in self._f:
            self._cur_prec = rel_prec = x.parent().prec()
            # Go a bit beyond so we're not constantly re-computing.
            max = x.parent()(1.1) * x + 10
            abs_prec = (-self.approximate(max).log2() + rel_prec + 2 * max.log2()).ceil()
            self._f = {}
            if sys.getrecursionlimit() < max + 10:
                sys.setrecursionlimit(int(max) + 10)
            self._compute_power_series(max.floor(), abs_prec, cache_ring=x.parent())
        return self._f[n](2 * (x - n - x.parent()(0.5)))
Exemplo n.º 4
0
def zeta_symmetric(s):
    r"""
    Completed function `\xi(s)` that satisfies
    `\xi(s) = \xi(1-s)` and has zeros at the same points as the
    Riemann zeta function.

    INPUT:


    -  ``s`` - real or complex number


    If s is a real number the computation is done using the MPFR
    library. When the input is not real, the computation is done using
    the PARI C library.

    More precisely,

    .. MATH::

                xi(s) = \gamma(s/2 + 1) * (s-1) * \pi^{-s/2} * \zeta(s).



    EXAMPLES::

        sage: zeta_symmetric(0.7)
        0.497580414651127
        sage: zeta_symmetric(1-0.7)
        0.497580414651127
        sage: RR = RealField(200)
        sage: zeta_symmetric(RR(0.7))
        0.49758041465112690357779107525638385212657443284080589766062
        sage: C.<i> = ComplexField()
        sage: zeta_symmetric(0.5 + i*14.0)
        0.000201294444235258 + 1.49077798716757e-19*I
        sage: zeta_symmetric(0.5 + i*14.1)
        0.0000489893483255687 + 4.40457132572236e-20*I
        sage: zeta_symmetric(0.5 + i*14.2)
        -0.0000868931282620101 + 7.11507675693612e-20*I

    REFERENCE:

    - I copied the definition of xi from
      http://web.viu.ca/pughg/RiemannZeta/RiemannZetaLong.html
    """
    if not (is_ComplexNumber(s) or is_RealNumber(s)):
        s = ComplexField()(s)

    R = s.parent()
    if s == 1:  # deal with poles, hopefully
        return R(0.5)

    return (s / 2 + 1).gamma() * (s - 1) * (R.pi()**(-s / 2)) * s.zeta()
Exemplo n.º 5
0
def zeta_symmetric(s):
    r"""
    Completed function `\xi(s)` that satisfies
    `\xi(s) = \xi(1-s)` and has zeros at the same points as the
    Riemann zeta function.

    INPUT:


    -  ``s`` - real or complex number


    If s is a real number the computation is done using the MPFR
    library. When the input is not real, the computation is done using
    the PARI C library.

    More precisely,

    .. math::

                xi(s) = \gamma(s/2 + 1) * (s-1) * \pi^{-s/2} * \zeta(s).



    EXAMPLES::

        sage: zeta_symmetric(0.7)
        0.497580414651127
        sage: zeta_symmetric(1-0.7)
        0.497580414651127
        sage: RR = RealField(200)
        sage: zeta_symmetric(RR(0.7))
        0.49758041465112690357779107525638385212657443284080589766062
        sage: C.<i> = ComplexField()
        sage: zeta_symmetric(0.5 + i*14.0)
        0.000201294444235258 + 1.49077798716757e-19*I
        sage: zeta_symmetric(0.5 + i*14.1)
        0.0000489893483255687 + 4.40457132572236e-20*I
        sage: zeta_symmetric(0.5 + i*14.2)
        -0.0000868931282620101 + 7.11507675693612e-20*I

    REFERENCE:

    - I copied the definition of xi from
      http://web.viu.ca/pughg/RiemannZeta/RiemannZetaLong.html
    """
    if not (is_ComplexNumber(s) or is_RealNumber(s)):
        s = ComplexField()(s)

    R = s.parent()
    if s == 1:  # deal with poles, hopefully
        return R(0.5)

    return (s / 2 + 1).gamma() * (s - 1) * (R.pi() ** (-s / 2)) * s.zeta()
Exemplo n.º 6
0
    def to_cartesian(self, func, params=None):
        """
        Returns a 3-tuple of functions, parameterized over ``params``, that
        represents the Cartesian coordinates of the value of ``func``.

        INPUT:

         - ``func`` - A function in this coordinate space. Corresponds to the
           independent variable.

         - ``params`` - The parameters of ``func``. Corresponds to the dependent
           variables.

        EXAMPLES::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(x, y) = 2*x+y
            sage: T.to_cartesian(f, [x, y])
            (x + y, x - y, 2*x + y)
            sage: [h(1,2) for h in T.to_cartesian(lambda x,y: 2*x+y)]
            [3.0, -1.0, 4.0]

        We try to return a function having the same variable names as
        the function passed in::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(a, b) = 2*a+b
            sage: T.to_cartesian(f, [a, b])
            (a + b, a - b, 2*a + b)
            sage: t1,t2,t3=T.to_cartesian(lambda a,b: 2*a+b)
            sage: import inspect
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t2)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t3)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: def g(a,b): return 2*a+b
            sage: t1,t2,t3=T.to_cartesian(g)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: t1,t2,t3=T.to_cartesian(2*a+b)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)

        If we cannot guess the right parameter names, then the
        parameters are named `u` and `v`::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: t1,t2,t3=T.to_cartesian(operator.add)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['u', 'v'], varargs=None, keywords=None, defaults=None)
            sage: [h(1,2) for h in T.to_cartesian(operator.mul)]
            [3.0, -1.0, 2.0]
            sage: [h(u=1,v=2) for h in T.to_cartesian(operator.mul)]
            [3.0, -1.0, 2.0]

        The output of the function ``func`` is coerced to a float when
        it is evaluated if the function is something like a lambda or
        python callable. This takes care of situations like f returning a
        singleton numpy array, for example.

            sage: from numpy import array
            sage: v_phi=array([ 0.,  1.57079637,  3.14159274, 4.71238911,  6.28318548])
            sage: v_theta=array([ 0.,  0.78539819,  1.57079637,  2.35619456,  3.14159274])
            sage: m_r=array([[ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422],
            ....: [ 0.16763356,  0.19993708,  0.31403568,  0.47359696, 0.55282422],
            ....: [ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422],
            ....: [ 0.16763356,  0.19993708,  0.31403568,  0.47359696, 0.55282422],
            ....: [ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422]])
            sage: import scipy.interpolate
            sage: f=scipy.interpolate.RectBivariateSpline(v_phi,v_theta,m_r)
            sage: spherical_plot3d(f,(0,2*pi),(0,pi))
            Graphics3d Object

        """
        from sage.symbolic.expression import is_Expression
        from sage.rings.real_mpfr import is_RealNumber
        from sage.rings.integer import is_Integer
        if params is not None and (is_Expression(func) or is_RealNumber(func)
                                   or is_Integer(func)):
            return self.transform(
                **{
                    self.dep_var: func,
                    self.indep_vars[0]: params[0],
                    self.indep_vars[1]: params[1]
                })
        else:
            # func might be a lambda or a Python callable; this makes it slightly
            # more complex.
            import sage.symbolic.ring
            dep_var_dummy = sage.symbolic.ring.var(self.dep_var)
            indep_var_dummies = sage.symbolic.ring.var(','.join(
                self.indep_vars))
            transformation = self.transform(
                **{
                    self.dep_var: dep_var_dummy,
                    self.indep_vars[0]: indep_var_dummies[0],
                    self.indep_vars[1]: indep_var_dummies[1]
                })
            if params is None:
                if callable(func):
                    params = _find_arguments_for_callable(func)
                    if params is None:
                        params = ['u', 'v']
                else:
                    raise ValueError("function is not callable")

            def subs_func(t):
                # We use eval so that the lambda function has the same
                # variable names as the original function
                ll = """lambda {x},{y}: t.subs({{
                    dep_var_dummy: float(func({x}, {y})),
                    indep_var_dummies[0]: float({x}),
                    indep_var_dummies[1]: float({y})
                }})""".format(x=params[0], y=params[1])
                return eval(
                    ll,
                    dict(t=t,
                         func=func,
                         dep_var_dummy=dep_var_dummy,
                         indep_var_dummies=indep_var_dummies))

            return [subs_func(_) for _ in transformation]
Exemplo n.º 7
0
    def to_cartesian(self, func, params=None):
        """
        Returns a 3-tuple of functions, parameterized over ``params``, that
        represents the Cartesian coordinates of the value of ``func``.

        INPUT:

         - ``func`` - A function in this coordinate space. Corresponds to the
           independent variable.

         - ``params`` - The parameters of func. Corresponds to the dependent
           variables.

        EXAMPLE::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(x, y) = 2*x+y
            sage: T.to_cartesian(f, [x, y])
            (x + y, x - y, 2*x + y)
            sage: [h(1,2) for h in T.to_cartesian(lambda x,y: 2*x+y)]
            [3.0, -1.0, 4.0]

        We try to return a function having the same variable names as
        the function passed in::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(a, b) = 2*a+b
            sage: T.to_cartesian(f, [a, b])
            (a + b, a - b, 2*a + b)
            sage: t1,t2,t3=T.to_cartesian(lambda a,b: 2*a+b)
            sage: import inspect
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t2)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t3)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: def g(a,b): return 2*a+b
            sage: t1,t2,t3=T.to_cartesian(g)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: t1,t2,t3=T.to_cartesian(2*a+b)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)

        If we cannot guess the right parameter names, then the
        parameters are named `u` and `v`::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: t1,t2,t3=T.to_cartesian(operator.add)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['u', 'v'], varargs=None, keywords=None, defaults=None)
            sage: [h(1,2) for h in T.to_cartesian(operator.mul)]
            [3.0, -1.0, 2.0]
            sage: [h(u=1,v=2) for h in T.to_cartesian(operator.mul)]
            [3.0, -1.0, 2.0]

        The output of the function `func` is coerced to a float when
        it is evaluated if the function is something like a lambda or
        python callable. This takes care of situations like f returning a
        singleton numpy array, for example.

            sage: from numpy import array
            sage: v_phi=array([ 0.,  1.57079637,  3.14159274, 4.71238911,  6.28318548])
            sage: v_theta=array([ 0.,  0.78539819,  1.57079637,  2.35619456,  3.14159274])
            sage: m_r=array([[ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422],
            ... [ 0.16763356,  0.19993708,  0.31403568,  0.47359696, 0.55282422],
            ... [ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422],
            ... [ 0.16763356,  0.19993708,  0.31403568,  0.47359696, 0.55282422],
            ... [ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422]])
            sage: import scipy.interpolate
            sage: f=scipy.interpolate.RectBivariateSpline(v_phi,v_theta,m_r)
            sage: spherical_plot3d(f,(0,2*pi),(0,pi))
            Graphics3d Object

        """
        from sage.symbolic.expression import is_Expression
        from sage.rings.real_mpfr import is_RealNumber
        from sage.rings.integer import is_Integer
        if params is not None and (is_Expression(func) or is_RealNumber(func) or is_Integer(func)):
            return self.transform(**{
                self.dep_var: func,
                self.indep_vars[0]: params[0],
                self.indep_vars[1]: params[1]
            })
        else:
            # func might be a lambda or a Python callable; this makes it slightly
            # more complex.
            import sage.symbolic.ring
            dep_var_dummy = sage.symbolic.ring.var(self.dep_var)
            indep_var_dummies = sage.symbolic.ring.var(','.join(self.indep_vars))
            transformation = self.transform(**{
                self.dep_var: dep_var_dummy,
                self.indep_vars[0]: indep_var_dummies[0],
                self.indep_vars[1]: indep_var_dummies[1]
            })
            if params is None:
                if callable(func):
                    params = _find_arguments_for_callable(func)
                    if params is None:
                        params=['u','v']
                else:
                    raise ValueError("function is not callable")
            def subs_func(t):
                # We use eval so that the lambda function has the same
                # variable names as the original function
                ll="""lambda {x},{y}: t.subs({{
                    dep_var_dummy: float(func({x}, {y})),
                    indep_var_dummies[0]: float({x}),
                    indep_var_dummies[1]: float({y})
                }})""".format(x=params[0], y=params[1])
                return eval(ll,dict(t=t, func=func, dep_var_dummy=dep_var_dummy,
                                    indep_var_dummies=indep_var_dummies))
            return [subs_func(_) for _ in transformation]
Exemplo n.º 8
0
    def to_cartesian(self, func, params=None):
        """
        Returns a 3-tuple of functions, parameterized over ``params``, that
        represents the cartesian coordinates of the value of ``func``.

        INPUT:

         - ``func`` - A function in this coordinate space. Corresponds to the
           independent variable.

         - ``params`` - The parameters of func. Corresponds to the dependent
           variables.

        EXAMPLE::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(x, y) = 2*x+y
            sage: T.to_cartesian(f, [x, y])
            (x + y, x - y, 2*x + y)
            sage: [h(1,2) for h in T.to_cartesian(lambda x,y: 2*x+y)]
            [3, -1, 4]
            
        We try to return a function having the same variable names as
        the function passed in::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(a, b) = 2*a+b
            sage: T.to_cartesian(f, [a, b])
            (a + b, a - b, 2*a + b)
            sage: t1,t2,t3=T.to_cartesian(lambda a,b: 2*a+b)
            sage: import inspect
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t2)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t3)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: def g(a,b): return 2*a+b
            sage: t1,t2,t3=T.to_cartesian(g)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: t1,t2,t3=T.to_cartesian(2*a+b)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)

        If we cannot guess the right parameter names, then the
        parameters are named `u` and `v`::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: t1,t2,t3=T.to_cartesian(operator.add)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['u', 'v'], varargs=None, keywords=None, defaults=None)
            sage: [h(1,2) for h in T.to_cartesian(operator.mul)]
            [3, -1, 2]
            sage: [h(u=1,v=2) for h in T.to_cartesian(operator.mul)]
            [3, -1, 2]

        """
        from sage.symbolic.expression import is_Expression
        from sage.rings.real_mpfr import is_RealNumber
        from sage.rings.integer import is_Integer
        if params is not None and (is_Expression(func) or is_RealNumber(func) or is_Integer(func)):
            return self.transform(**{
                self.dep_var: func,
                self.indep_vars[0]: params[0],
                self.indep_vars[1]: params[1]
            })
        else:
            # func might be a lambda or a Python callable; this makes it slightly
            # more complex.
            import sage.symbolic.ring
            dep_var_dummy = sage.symbolic.ring.var(self.dep_var)
            indep_var_dummies = sage.symbolic.ring.var(','.join(self.indep_vars))
            transformation = self.transform(**{
                self.dep_var: dep_var_dummy,
                self.indep_vars[0]: indep_var_dummies[0],
                self.indep_vars[1]: indep_var_dummies[1]
            })
            if params is None:
                if callable(func):
                    params = _find_arguments_for_callable(func)
                    if params is None:
                        params=['u','v']
                else:
                    raise ValueError, "function is not callable"
            def subs_func(t):
                # We use eval so that the lambda function has the same 
                # variable names as the original function
                ll="""lambda {x},{y}: t.subs({{
                    dep_var_dummy: func({x}, {y}),
                    indep_var_dummies[0]: {x},
                    indep_var_dummies[1]: {y}
                }})""".format(x=params[0], y=params[1])
                return eval(ll,dict(t=t, func=func, dep_var_dummy=dep_var_dummy, 
                                    indep_var_dummies=indep_var_dummies))
            return map(subs_func, transformation)