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