Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Other functions
TESTS:
Check that gamma function imports are deprecated (:trac:`24411`)::
sage: from sage.functions.other import beta sage: beta(x, x) doctest:...: DeprecationWarning: Importing beta from here is deprecated. If you need to use it, please import it directly from sage.functions.gamma See http://trac.sagemath.org/24411 for details. beta(x, x) """ from __future__ import print_function from six.moves import range from six import integer_types
from sage.misc.lazy_import import lazy_import lazy_import('sage.functions.gamma', ('gamma', 'log_gamma', 'gamma_inc', 'incomplete_gamma', 'gamma_inc_lower', 'psi', 'beta'), deprecation=24411)
from sage.symbolic.function import GinacFunction, BuiltinFunction from sage.symbolic.expression import Expression from sage.libs.pynac.pynac import (register_symbol, symbol_table, py_factorial_py, I) from sage.symbolic.all import SR from sage.rings.all import Integer, Rational, RealField, ZZ, ComplexField from sage.rings.complex_number import is_ComplexNumber from sage.misc.latex import latex from sage.misc.decorators import rename_keyword import math
from sage.structure.element import coercion_model
# avoid name conflicts with `parent` as a function parameter from sage.structure.all import parent as s_parent
from sage.symbolic.constants import pi from sage.functions.log import exp from sage.functions.trig import arctan2 from sage.functions.exp_integral import Ei from sage.libs.mpmath import utils as mpmath_utils from sage.arith.all import binomial as arith_binomial
one_half = SR.one() / SR(2)
class Function_abs(GinacFunction): def __init__(self): r""" The absolute value function.
EXAMPLES::
sage: var('x y') (x, y) sage: abs(x) abs(x) sage: abs(x^2 + y^2) abs(x^2 + y^2) sage: abs(-2) 2 sage: sqrt(x^2) sqrt(x^2) sage: abs(sqrt(x)) sqrt(abs(x)) sage: complex(abs(3*I)) (3+0j)
sage: f = sage.functions.other.Function_abs() sage: latex(f) \mathrm{abs} sage: latex(abs(x)) {\left| x \right|} sage: abs(x)._sympy_() Abs(x)
Test pickling::
sage: loads(dumps(abs(x))) abs(x)
TESTS:
Check that :trac:`12588` is fixed::
sage: abs(pi*I) pi sage: abs(pi*I*catalan) catalan*pi sage: abs(pi*catalan*x) catalan*pi*abs(x) sage: abs(pi*I*catalan*x) catalan*pi*abs(x) sage: abs(1.0j*pi) 1.00000000000000*pi sage: abs(I*x) abs(x) sage: abs(I*pi) pi sage: abs(I*log(2)) log(2) sage: abs(I*e^5) e^5 sage: abs(log(1/2)) -log(1/2) sage: abs(log(3/2)) log(3/2) sage: abs(log(1/2)*log(1/3)) log(1/2)*log(1/3) sage: abs(log(1/2)*log(1/3)*log(1/4)) -log(1/2)*log(1/3)*log(1/4) sage: abs(log(1/2)*log(1/3)*log(1/4)*i) -log(1/2)*log(1/3)*log(1/4) sage: abs(log(x)) abs(log(x)) sage: abs(zeta(I)) abs(zeta(I)) sage: abs(e^2*x) abs(x)*e^2 sage: abs((pi+e)*x) (pi + e)*abs(x) """ conversions=dict(sympy='Abs', mathematica='Abs', giac='abs'))
abs = abs_symbolic = Function_abs()
@rename_keyword(deprecation=22079, maximum_bits="bits") def _eval_floor_ceil(self, x, method, bits=0, **kwds): """ Helper function to compute ``floor(x)`` or ``ceil(x)``.
INPUT:
- ``x`` -- a number
- ``method`` -- should be either ``"floor"`` or ``"ceil"``
- ``bits`` -- how many bits to use before giving up
See :class:`Function_floor` and :class:`Function_ceil` for examples and tests.
TESTS::
sage: numbers = [SR(10^100 + exp(-100)), SR(10^100 - exp(-100)), SR(10^100)] sage: numbers += [-n for n in numbers] sage: for n in numbers: ....: f = floor(n) ....: c = ceil(n) ....: if f == c: ....: assert n in ZZ ....: else: ....: assert f + 1 == c
A test from :trac:`12121`::
sage: e1 = pi - continued_fraction(pi).convergent(2785) sage: e2 = e - continued_fraction(e).convergent(1500) sage: f = e1/e2 sage: f = 1 / (f - continued_fraction(f).convergent(1000)) sage: f = f - continued_fraction(f).convergent(1) sage: floor(f, bits=10000) -1 sage: ceil(f, bits=10000) 0
These don't work but fail gracefully::
sage: ceil(Infinity) Traceback (most recent call last): ... ValueError: Calling ceil() on infinity or NaN sage: ceil(NaN) Traceback (most recent call last): ... ValueError: Calling ceil() on infinity or NaN
TESTS::
sage: floor(pi, maximum_bits=0) doctest:...: DeprecationWarning: use the option 'bits' instead of 'maximum_bits' See http://trac.sagemath.org/22079 for details. 3 """ # First, some obvious things... else:
# The strategy is to convert the number to an interval field and # hope that this interval will have a unique floor/ceiling. # # There are 2 reasons why this could fail: # (A) The expression is very complicated and we simply require # more bits. # (B) The expression is a non-obvious exact integer. In this # case, adding bits will not help since an interval around # an integer will not have a unique floor/ceiling, no matter # how many bits are used. # # The strategy is to first reduce the absolute diameter of the # interval until its size is at most 10^(-6). Then we check for # (B) by simplifying the expression.
# Might it be needed to simplify x? This only applies for # elements of SR.
# An integer which is close to x. We use this to increase precision # by subtracting this guess before converting to an interval field. # This mostly helps with the case that x is close to, but not equal # to, an exact integer.
# We do not use the target number of bits immediately, we just use # it as indication of when to stop. # Add one more attempt as long as the precision is less # than requested
else: # If we cannot compute a numerical enclosure, leave the # expression unevaluated. # We have a very bad approximation => increase the number # of bits a lot # Increase number of bits to get to a diameter less than # 2^(-32), assuming that the diameter scales as 2^(-bits)
# Compute ceil/floor of both ends of the interval: # if these match, we are done!
# Compute a better guess for the next attempt. Since diam < 1, # there is a unique integer in our interval. This integer equals # the ceil of the lower bound and the floor of the upper bound. else:
class Function_ceil(BuiltinFunction): def __init__(self): r""" The ceiling function.
The ceiling of `x` is computed in the following manner.
#. The ``x.ceil()`` method is called and returned if it is there. If it is not, then Sage checks if `x` is one of Python's native numeric data types. If so, then it calls and returns ``Integer(math.ceil(x))``.
#. Sage tries to convert `x` into a ``RealIntervalField`` with 53 bits of precision. Next, the ceilings of the endpoints are computed. If they are the same, then that value is returned. Otherwise, the precision of the ``RealIntervalField`` is increased until they do match up or it reaches ``bits`` of precision.
#. If none of the above work, Sage returns a ``Expression`` object.
EXAMPLES::
sage: a = ceil(2/5 + x) sage: a ceil(x + 2/5) sage: a(x=4) 5 sage: a(x=4.0) 5 sage: ZZ(a(x=3)) 4 sage: a = ceil(x^3 + x + 5/2); a ceil(x^3 + x + 5/2) sage: a.simplify() ceil(x^3 + x + 1/2) + 2 sage: a(x=2) 13
::
sage: ceil(sin(8)/sin(2)) 2
::
sage: ceil(5.4) 6 sage: type(ceil(5.4)) <type 'sage.rings.integer.Integer'>
::
sage: ceil(factorial(50)/exp(1)) 11188719610782480504630258070757734324011354208865721592720336801 sage: ceil(SR(10^50 + 10^(-50))) 100000000000000000000000000000000000000000000000001 sage: ceil(SR(10^50 - 10^(-50))) 100000000000000000000000000000000000000000000000000
Small numbers which are extremely close to an integer are hard to deal with::
sage: ceil((33^100 + 1)^(1/100)) Traceback (most recent call last): ... ValueError: cannot compute ceil(...) using 256 bits of precision
This can be fixed by giving a sufficiently large ``bits`` argument::
sage: ceil((33^100 + 1)^(1/100), bits=500) Traceback (most recent call last): ... ValueError: cannot compute ceil(...) using 512 bits of precision sage: ceil((33^100 + 1)^(1/100), bits=1000) 34
::
sage: ceil(sec(e)) -1
sage: latex(ceil(x)) \left \lceil x \right \rceil sage: ceil(x)._sympy_() ceiling(x)
::
sage: import numpy sage: a = numpy.linspace(0,2,6) sage: ceil(a) array([ 0., 1., 1., 2., 2., 2.])
Test pickling::
sage: loads(dumps(ceil)) ceil """ conversions=dict(maxima='ceiling', sympy='ceiling', giac='ceil'))
def _print_latex_(self, x): r""" EXAMPLES::
sage: latex(ceil(x)) # indirect doctest \left \lceil x \right \rceil """
#FIXME: this should be moved to _eval_ def __call__(self, x, **kwds): """ Allows an object of this class to behave like a function. If ``ceil`` is an instance of this class, we can do ``ceil(n)`` to get the ceiling of ``n``.
TESTS::
sage: ceil(SR(10^50 + 10^(-50))) 100000000000000000000000000000000000000000000000001 sage: ceil(SR(10^50 - 10^(-50))) 100000000000000000000000000000000000000000000000000 sage: ceil(int(10^50)) 100000000000000000000000000000000000000000000000000 sage: ceil((1725033*pi - 5419351)/(25510582*pi - 80143857)) -2 """
def _eval_(self, x): """ EXAMPLES::
sage: ceil(x).subs(x==7.5) 8 sage: ceil(x) ceil(x) """ return Integer(x) return Integer(math.ceil(x))
ceil = Function_ceil()
class Function_floor(BuiltinFunction): def __init__(self): r""" The floor function.
The floor of `x` is computed in the following manner.
#. The ``x.floor()`` method is called and returned if it is there. If it is not, then Sage checks if `x` is one of Python's native numeric data types. If so, then it calls and returns ``Integer(math.floor(x))``.
#. Sage tries to convert `x` into a ``RealIntervalField`` with 53 bits of precision. Next, the floors of the endpoints are computed. If they are the same, then that value is returned. Otherwise, the precision of the ``RealIntervalField`` is increased until they do match up or it reaches ``bits`` of precision.
#. If none of the above work, Sage returns a symbolic ``Expression`` object.
EXAMPLES::
sage: floor(5.4) 5 sage: type(floor(5.4)) <type 'sage.rings.integer.Integer'> sage: var('x') x sage: a = floor(5.4 + x); a floor(x + 5.40000000000000) sage: a.simplify() floor(x + 0.4000000000000004) + 5 sage: a(x=2) 7
::
sage: floor(cos(8) / cos(2)) 0 sage: floor(log(4) / log(2)) 2 sage: a = floor(5.4 + x); a floor(x + 5.40000000000000) sage: a.subs(x==2) 7 sage: floor(log(2^(3/2)) / log(2) + 1/2) 2 sage: floor(log(2^(-3/2)) / log(2) + 1/2) -1
::
sage: floor(factorial(50)/exp(1)) 11188719610782480504630258070757734324011354208865721592720336800 sage: floor(SR(10^50 + 10^(-50))) 100000000000000000000000000000000000000000000000000 sage: floor(SR(10^50 - 10^(-50))) 99999999999999999999999999999999999999999999999999 sage: floor(int(10^50)) 100000000000000000000000000000000000000000000000000
Small numbers which are extremely close to an integer are hard to deal with::
sage: floor((33^100 + 1)^(1/100)) Traceback (most recent call last): ... ValueError: cannot compute floor(...) using 256 bits of precision
This can be fixed by giving a sufficiently large ``bits`` argument::
sage: floor((33^100 + 1)^(1/100), bits=500) Traceback (most recent call last): ... ValueError: cannot compute floor(...) using 512 bits of precision sage: floor((33^100 + 1)^(1/100), bits=1000) 33
::
sage: import numpy sage: a = numpy.linspace(0,2,6) sage: floor(a) array([ 0., 0., 0., 1., 1., 2.]) sage: floor(x)._sympy_() floor(x)
Test pickling::
sage: loads(dumps(floor)) floor """ conversions=dict(sympy='floor', giac='floor'))
def _print_latex_(self, x): r""" EXAMPLES::
sage: latex(floor(x)) \left \lfloor x \right \rfloor """
#FIXME: this should be moved to _eval_ def __call__(self, x, **kwds): """ Allows an object of this class to behave like a function. If ``floor`` is an instance of this class, we can do ``floor(n)`` to obtain the floor of ``n``.
TESTS::
sage: floor(SR(10^50 + 10^(-50))) 100000000000000000000000000000000000000000000000000 sage: floor(SR(10^50 - 10^(-50))) 99999999999999999999999999999999999999999999999999 sage: floor(int(10^50)) 100000000000000000000000000000000000000000000000000 sage: floor((1725033*pi - 5419351)/(25510582*pi - 80143857)) -3 """
def _eval_(self, x): """ EXAMPLES::
sage: floor(x).subs(x==7.5) 7 sage: floor(x) floor(x) """ return Integer(x) return Integer(math.floor(x))
floor = Function_floor()
class Function_Order(GinacFunction): def __init__(self): r""" The order function.
This function gives the order of magnitude of some expression, similar to `O`-terms.
.. SEEALSO::
:meth:`~sage.symbolic.expression.Expression.Order`, :mod:`~sage.rings.big_oh`
EXAMPLES::
sage: x = SR('x') sage: x.Order() Order(x) sage: (x^2 + x).Order() Order(x^2 + x) sage: x.Order()._sympy_() O(x)
TESTS:
Check that :trac:`19425` is resolved::
sage: x.Order().operator() Order """ GinacFunction.__init__(self, "Order", conversions=dict(sympy='O'), latex_name=r"\mathcal{O}")
Order = Function_Order()
class Function_frac(BuiltinFunction): def __init__(self): r""" The fractional part function `\{x\}`.
``frac(x)`` is defined as `\{x\} = x - \lfloor x\rfloor`.
EXAMPLES::
sage: frac(5.4) 0.400000000000000 sage: type(frac(5.4)) <type 'sage.rings.real_mpfr.RealNumber'> sage: frac(456/123) 29/41 sage: var('x') x sage: a = frac(5.4 + x); a frac(x + 5.40000000000000) sage: frac(cos(8)/cos(2)) cos(8)/cos(2) sage: latex(frac(x)) \operatorname{frac}\left(x\right) sage: frac(x)._sympy_() frac(x)
Test pickling::
sage: loads(dumps(floor)) floor """ BuiltinFunction.__init__(self, "frac", conversions=dict(sympy='frac'), latex_name=r"\operatorname{frac}")
def _evalf_(self, x, **kwds): """ EXAMPLES::
sage: frac(pi).n() 0.141592653589793 sage: frac(pi).n(200) 0.14159265358979323846264338327950288419716939937510582097494 """
def _eval_(self, x): """ EXAMPLES::
sage: frac(x).subs(x==7.5) 0.500000000000000 sage: frac(x) frac(x) """ return Integer(0) return x - Integer(math.floor(x))
frac = Function_frac()
def _do_sqrt(x, prec=None, extend=True, all=False): r""" Used internally to compute the square root of x.
INPUT:
- ``x`` - a number
- ``prec`` - None (default) or a positive integer (bits of precision) If not None, then compute the square root numerically to prec bits of precision.
- ``extend`` - bool (default: True); this is a place holder, and is always ignored since in the symbolic ring everything has a square root.
- ``extend`` - bool (default: True); whether to extend the base ring to find roots. The extend parameter is ignored if prec is a positive integer.
- ``all`` - bool (default: False); whether to return a list of all the square roots of x.
EXAMPLES::
sage: from sage.functions.other import _do_sqrt sage: _do_sqrt(3) sqrt(3) sage: _do_sqrt(3,prec=10) 1.7 sage: _do_sqrt(3,prec=100) 1.7320508075688772935274463415 sage: _do_sqrt(3,all=True) [sqrt(3), -sqrt(3)]
Note that the extend parameter is ignored in the symbolic ring::
sage: _do_sqrt(3,extend=False) sqrt(3) """ else: else:
else: return [z]
def sqrt(x, *args, **kwds): r""" INPUT:
- ``x`` - a number
- ``prec`` - integer (default: None): if None, returns an exact square root; otherwise returns a numerical square root if necessary, to the given bits of precision.
- ``extend`` - bool (default: True); this is a place holder, and is always ignored or passed to the sqrt function for x, since in the symbolic ring everything has a square root.
- ``all`` - bool (default: False); if True, return all square roots of self, instead of just one.
EXAMPLES::
sage: sqrt(-1) I sage: sqrt(2) sqrt(2) sage: sqrt(2)^2 2 sage: sqrt(4) 2 sage: sqrt(4,all=True) [2, -2] sage: sqrt(x^2) sqrt(x^2)
For a non-symbolic square root, there are a few options. The best is to numerically approximate afterward::
sage: sqrt(2).n() 1.41421356237310 sage: sqrt(2).n(prec=100) 1.4142135623730950488016887242
Or one can input a numerical type.
sage: sqrt(2.) 1.41421356237310 sage: sqrt(2.000000000000000000000000) 1.41421356237309504880169 sage: sqrt(4.0) 2.00000000000000
To prevent automatic evaluation, one can use the ``hold`` parameter after coercing to the symbolic ring::
sage: sqrt(SR(4),hold=True) sqrt(4) sage: sqrt(4,hold=True) Traceback (most recent call last): ... TypeError: _do_sqrt() got an unexpected keyword argument 'hold'
This illustrates that the bug reported in :trac:`6171` has been fixed::
sage: a = 1.1 sage: a.sqrt(prec=100) # this is supposed to fail Traceback (most recent call last): ... TypeError: sqrt() got an unexpected keyword argument 'prec' sage: sqrt(a, prec=100) 1.0488088481701515469914535137 sage: sqrt(4.00, prec=250) 2.0000000000000000000000000000000000000000000000000000000000000000000000000
One can use numpy input as well::
sage: import numpy sage: a = numpy.arange(2,5) sage: sqrt(a) array([ 1.41421356, 1.73205081, 2. ]) """ # The following includes TypeError to catch cases where sqrt # is called with a "prec" keyword, for example, but the sqrt # method for x doesn't accept such a keyword.
# register sqrt in pynac symbol_table for conversion back from other systems register_symbol(sqrt, dict(mathematica='Sqrt')) symbol_table['functions']['sqrt'] = sqrt
Function_sqrt = type('deprecated_sqrt', (), {'__call__': staticmethod(sqrt), '__setstate__': lambda x, y: None})
class Function_arg(BuiltinFunction): def __init__(self): r""" The argument function for complex numbers.
EXAMPLES::
sage: arg(3+i) arctan(1/3) sage: arg(-1+i) 3/4*pi sage: arg(2+2*i) 1/4*pi sage: arg(2+x) arg(x + 2) sage: arg(2.0+i+x) arg(x + 2.00000000000000 + 1.00000000000000*I) sage: arg(-3) pi sage: arg(3) 0 sage: arg(0) 0
sage: latex(arg(x)) {\rm arg}\left(x\right) sage: maxima(arg(x)) atan2(0,_SAGE_VAR_x) sage: maxima(arg(2+i)) atan(1/2) sage: maxima(arg(sqrt(2)+i)) atan(1/sqrt(2)) sage: arg(x)._sympy_() arg(x)
sage: arg(2+i) arctan(1/2) sage: arg(sqrt(2)+i) arg(sqrt(2) + I) sage: arg(sqrt(2)+i).simplify() arctan(1/2*sqrt(2))
TESTS::
sage: arg(0.0) 0.000000000000000 sage: arg(3.0) 0.000000000000000 sage: arg(-2.5) 3.14159265358979 sage: arg(2.0+3*i) 0.982793723247329 """ BuiltinFunction.__init__(self, "arg", conversions=dict(maxima='carg', mathematica='Arg', sympy='arg', giac='arg'))
def _eval_(self, x): """ EXAMPLES::
sage: arg(3+i) arctan(1/3) sage: arg(-1+i) 3/4*pi sage: arg(2+2*i) 1/4*pi sage: arg(2+x) arg(x + 2) sage: arg(2.0+i+x) arg(x + 2.00000000000000 + 1.00000000000000*I) sage: arg(-3) pi sage: arg(3) 0 sage: arg(0) 0 sage: arg(sqrt(2)+i) arg(sqrt(2) + I)
""" return x else: else:
def _evalf_(self, x, parent=None, algorithm=None): """ EXAMPLES::
sage: arg(0.0) 0.000000000000000 sage: arg(3.0) 0.000000000000000 sage: arg(3.00000000000000000000000000) 0.00000000000000000000000000 sage: arg(3.00000000000000000000000000).prec() 90 sage: arg(ComplexIntervalField(90)(3)).prec() 90 sage: arg(ComplexIntervalField(90)(3)).parent() Real Interval Field with 90 bits of precision sage: arg(3.0r) 0.0 sage: arg(RDF(3)) 0.0 sage: arg(RDF(3)).parent() Real Double Field sage: arg(-2.5) 3.14159265358979 sage: arg(2.0+3*i) 0.982793723247329
TESTS:
Make sure that the ``_evalf_`` method works when it receives a keyword argument ``parent`` :trac:`12289`::
sage: arg(5+I, hold=True).n() 0.197395559849881 """ # try to find a parent that support .arg() parent = s_parent(x)
arg=Function_arg()
############################ # Real and Imaginary Parts # ############################ class Function_real_part(GinacFunction): def __init__(self): r""" Returns the real part of the (possibly complex) input.
It is possible to prevent automatic evaluation using the ``hold`` parameter::
sage: real_part(I,hold=True) real_part(I)
To then evaluate again, we currently must use Maxima via :meth:`sage.symbolic.expression.Expression.simplify`::
sage: real_part(I,hold=True).simplify() 0
EXAMPLES::
sage: z = 1+2*I sage: real(z) 1 sage: real(5/3) 5/3 sage: a = 2.5 sage: real(a) 2.50000000000000 sage: type(real(a)) <type 'sage.rings.real_mpfr.RealLiteral'> sage: real(1.0r) 1.0 sage: real(complex(3, 4)) 3.0
Sage can recognize some expressions as real and accordingly return the identical argument::
sage: SR.var('x', domain='integer').real_part() x sage: SR.var('x', domain='integer').imag_part() 0 sage: real_part(sin(x)+x) x + sin(x) sage: real_part(x*exp(x)) x*e^x sage: imag_part(sin(x)+x) 0 sage: real_part(real_part(x)) x sage: forget()
TESTS::
sage: loads(dumps(real_part)) real_part sage: real_part(x)._sympy_() re(x)
Check if :trac:`6401` is fixed::
sage: latex(x.real()) \Re \left( x \right)
sage: f(x) = function('f')(x) sage: latex( f(x).real()) \Re \left( f\left(x\right) \right)
Check that some real part expansions evaluate correctly (:trac:`21614`)::
sage: real(sqrt(sin(x))).subs(x==0) 0 """ conversions=dict(maxima='realpart', sympy='re', giac='re'), alt_name="real")
def __call__(self, x, **kwargs): r""" TESTS::
sage: type(real(complex(3, 4))) <... 'float'> """ else:
real = real_part = Function_real_part()
class Function_imag_part(GinacFunction): def __init__(self): r""" Returns the imaginary part of the (possibly complex) input.
It is possible to prevent automatic evaluation using the ``hold`` parameter::
sage: imag_part(I,hold=True) imag_part(I)
To then evaluate again, we currently must use Maxima via :meth:`sage.symbolic.expression.Expression.simplify`::
sage: imag_part(I,hold=True).simplify() 1
TESTS::
sage: z = 1+2*I sage: imaginary(z) 2 sage: imag(z) 2 sage: imag(complex(3, 4)) 4.0 sage: loads(dumps(imag_part)) imag_part sage: imag_part(x)._sympy_() im(x)
Check if :trac:`6401` is fixed::
sage: latex(x.imag()) \Im \left( x \right)
sage: f(x) = function('f')(x) sage: latex( f(x).imag()) \Im \left( f\left(x\right) \right) """ conversions=dict(maxima='imagpart', sympy='im', giac='im'), alt_name="imag")
def __call__(self, x, **kwargs): r""" TESTS::
sage: type(imag(complex(3, 4))) <... 'float'> """ else:
imag = imag_part = imaginary = Function_imag_part()
############################ # Complex Conjugate # ############################ class Function_conjugate(GinacFunction): def __init__(self): r""" Returns the complex conjugate of the input.
It is possible to prevent automatic evaluation using the ``hold`` parameter::
sage: conjugate(I,hold=True) conjugate(I)
To then evaluate again, we currently must use Maxima via :meth:`sage.symbolic.expression.Expression.simplify`::
sage: conjugate(I,hold=True).simplify() -I
TESTS::
sage: x,y = var('x,y') sage: x.conjugate() conjugate(x) sage: _._sympy_() conjugate(x) sage: latex(conjugate(x)) \overline{x} sage: f = function('f') sage: latex(f(x).conjugate()) \overline{f\left(x\right)} sage: f = function('psi')(x,y) sage: latex(f.conjugate()) \overline{\psi\left(x, y\right)} sage: x.conjugate().conjugate() x sage: x.conjugate().operator() conjugate sage: x.conjugate().operator() == conjugate True
Check if :trac:`8755` is fixed::
sage: conjugate(sqrt(-3)) conjugate(sqrt(-3)) sage: conjugate(sqrt(3)) sqrt(3) sage: conjugate(sqrt(x)) conjugate(sqrt(x)) sage: conjugate(x^2) conjugate(x)^2 sage: var('y',domain='positive') y sage: conjugate(sqrt(y)) sqrt(y)
Check if :trac:`10964` is fixed::
sage: z= I*sqrt(-3); z I*sqrt(-3) sage: conjugate(z) -I*conjugate(sqrt(-3)) sage: var('a') a sage: conjugate(a*sqrt(-2)*sqrt(-3)) conjugate(sqrt(-2))*conjugate(sqrt(-3))*conjugate(a)
Check that sums are handled correctly::
sage: y = var('y', domain='real') sage: conjugate(y + I) y - I
Test pickling::
sage: loads(dumps(conjugate)) conjugate """ conversions=dict(sympy='conjugate', giac='conj'))
conjugate = Function_conjugate()
class Function_factorial(GinacFunction): def __init__(self): r""" Returns the factorial of `n`.
INPUT:
- ``n`` - any complex argument (except negative integers) or any symbolic expression
OUTPUT: an integer or symbolic expression
EXAMPLES::
sage: x = var('x') sage: factorial(0) 1 sage: factorial(4) 24 sage: factorial(10) 3628800 sage: factorial(6) == 6*5*4*3*2 True sage: f = factorial(x + factorial(x)); f factorial(x + factorial(x)) sage: f(x=3) 362880 sage: factorial(x)^2 factorial(x)^2
To prevent automatic evaluation use the ``hold`` argument::
sage: factorial(5,hold=True) factorial(5)
To then evaluate again, we currently must use Maxima via :meth:`sage.symbolic.expression.Expression.simplify`::
sage: factorial(5,hold=True).simplify() 120
We can also give input other than nonnegative integers. For other nonnegative numbers, the :func:`sage.functions.gamma.gamma` function is used::
sage: factorial(1/2) 1/2*sqrt(pi) sage: factorial(3/4) gamma(7/4) sage: factorial(2.3) 2.68343738195577
But negative input always fails::
sage: factorial(-32) Traceback (most recent call last): ... ValueError: factorial -- self = (-32) must be nonnegative
TESTS:
We verify that we can convert this function to Maxima and bring it back into Sage.::
sage: z = var('z') sage: factorial._maxima_init_() 'factorial' sage: maxima(factorial(z)) factorial(_SAGE_VAR_z) sage: _.sage() factorial(z) sage: _._sympy_() factorial(z) sage: k = var('k') sage: factorial(k) factorial(k)
sage: factorial(3.14) 7.173269190187...
Test latex typesetting::
sage: latex(factorial(x)) x! sage: latex(factorial(2*x)) \left(2 \, x\right)! sage: latex(factorial(sin(x))) \sin\left(x\right)! sage: latex(factorial(sqrt(x+1))) \left(\sqrt{x + 1}\right)! sage: latex(factorial(sqrt(x))) \sqrt{x}! sage: latex(factorial(x^(2/3))) \left(x^{\frac{2}{3}}\right)!
sage: latex(factorial) {\rm factorial}
Check that :trac:`11539` is fixed::
sage: (factorial(x) == 0).simplify() factorial(x) == 0 sage: maxima(factorial(x) == 0).sage() factorial(x) == 0 sage: y = var('y') sage: (factorial(x) == y).solve(x) [factorial(x) == y]
Check that :trac:`16166` is fixed::
sage: RBF=RealBallField(53) sage: factorial(RBF(4.2)) [32.5780960503313 +/- 6.72e-14]
Test pickling::
sage: loads(dumps(factorial)) factorial """ conversions=dict(maxima='factorial', mathematica='Factorial', sympy='factorial', fricas='factorial', giac='factorial'))
def _eval_(self, x): """ Evaluate the factorial function.
Note that this method overrides the eval method defined in GiNaC which calls numeric evaluation on all numeric input. We preserve exact results if the input is a rational number.
EXAMPLES::
sage: k = var('k') sage: k.factorial() factorial(k) sage: SR(1/2).factorial() 1/2*sqrt(pi) sage: SR(3/4).factorial() gamma(7/4) sage: SR(5).factorial() 120 sage: SR(3245908723049857203948572398475r).factorial() factorial(3245908723049857203948572398475) sage: SR(3245908723049857203948572398475).factorial() factorial(3245908723049857203948572398475) """
factorial = Function_factorial()
class Function_binomial(GinacFunction): def __init__(self): r""" Return the binomial coefficient
.. MATH::
\binom{x}{m} = x (x-1) \cdots (x-m+1) / m!
which is defined for `m \in \ZZ` and any `x`. We extend this definition to include cases when `x-m` is an integer but `m` is not by
.. MATH::
\binom{x}{m}= \binom{x}{x-m}
If `m < 0`, return `0`.
INPUT:
- ``x``, ``m`` - numbers or symbolic expressions. Either ``m`` or ``x-m`` must be an integer, else the output is symbolic.
OUTPUT: number or symbolic expression (if input is symbolic)
EXAMPLES::
sage: binomial(5,2) 10 sage: binomial(2,0) 1 sage: binomial(1/2, 0) 1 sage: binomial(3,-1) 0 sage: binomial(20,10) 184756 sage: binomial(-2, 5) -6 sage: binomial(RealField()('2.5'), 2) 1.87500000000000 sage: n=var('n'); binomial(n,2) 1/2*(n - 1)*n sage: n=var('n'); binomial(n,n) 1 sage: n=var('n'); binomial(n,n-1) n sage: binomial(2^100, 2^100) 1
::
sage: k, i = var('k,i') sage: binomial(k,i) binomial(k, i)
We can use a ``hold`` parameter to prevent automatic evaluation::
sage: SR(5).binomial(3, hold=True) binomial(5, 3) sage: SR(5).binomial(3, hold=True).simplify() 10
TESTS:
We verify that we can convert this function to Maxima and bring it back into Sage.
::
sage: n,k = var('n,k') sage: maxima(binomial(n,k)) binomial(_SAGE_VAR_n,_SAGE_VAR_k) sage: _.sage() binomial(n, k) sage: _._sympy_() binomial(n, k) sage: binomial._maxima_init_() 'binomial'
For polynomials::
sage: y = polygen(QQ, 'y') sage: binomial(y, 2).parent() Univariate Polynomial Ring in y over Rational Field
:trac:`16726`::
sage: binomial(CIF(1), 2) 0 sage: binomial(CIF(3), 2) 3
Test pickling::
sage: loads(dumps(binomial(n,k))) binomial(n, k) """ conversions=dict(maxima='binomial', mathematica='Binomial', sympy='binomial', fricas='binomial', giac='comb'))
def _binomial_sym(self, n, k): """ Expand the binomial formula symbolically when the second argument is an integer.
EXAMPLES::
sage: binomial._binomial_sym(x, 3) 1/6*(x - 1)*(x - 2)*x sage: binomial._binomial_sym(x, x) Traceback (most recent call last): ... ValueError: second argument must be an integer sage: binomial._binomial_sym(x, SR(3)) 1/6*(x - 1)*(x - 2)*x
sage: binomial._binomial_sym(x, 0r) 1 sage: binomial._binomial_sym(x, -1) 0
sage: y = polygen(QQ, 'y') sage: binomial._binomial_sym(y, 2).parent() Univariate Polynomial Ring in y over Rational Field """ else:
def _eval_(self, n, k): """ EXAMPLES::
sage: binomial._eval_(5, 3) 10 sage: type(binomial._eval_(5, 3)) <type 'sage.rings.integer.Integer'> sage: type(binomial._eval_(5., 3)) <type 'sage.rings.real_mpfr.RealNumber'> sage: binomial._eval_(x, 3) 1/6*(x - 1)*(x - 2)*x sage: binomial._eval_(x, x-2) 1/2*(x - 1)*x sage: n = var('n') sage: binomial._eval_(x, n) is None True
TESTS::
sage: y = polygen(QQ, 'y') sage: binomial._eval_(y, 2).parent() Univariate Polynomial Ring in y over Rational Field """
def _evalf_(self, n, k, parent=None, algorithm=None): """ EXAMPLES::
sage: binomial._evalf_(5.r, 3) 10.0 sage: type(binomial._evalf_(5.r, 3)) <... 'float'> sage: binomial._evalf_(1/2,1/1) 1/2 sage: binomial._evalf_(10^20+1/1,10^20) 100000000000000000001 sage: binomial._evalf_(SR(10**7),10**7) 1 sage: binomial._evalf_(3/2,SR(1/1)) 3/2 """
binomial = Function_binomial()
class Function_sum(BuiltinFunction): """ Placeholder symbolic sum function that is only accessible internally.
EXAMPLES::
sage: from sage.functions.other import symbolic_sum as ssum sage: r = ssum(x, x, 1, 10); r sum(x, x, 1, 10) sage: r.unhold() 55 """ def __init__(self): """ EXAMPLES::
sage: from sage.functions.other import symbolic_sum as ssum sage: maxima(ssum(x, x, 1, 10)) 55 """ BuiltinFunction.__init__(self, "sum", nargs=4, conversions=dict(maxima='sum'))
def _print_latex_(self, x, var, a, b): r""" EXAMPLES::
sage: from sage.functions.other import symbolic_sum as ssum sage: latex(ssum(x^2, x, 1, 10)) {\sum_{x=1}^{10} x^{2}} """ latex(b), latex(x))
symbolic_sum = Function_sum()
class Function_prod(BuiltinFunction): """ Placeholder symbolic product function that is only accessible internally.
EXAMPLES::
sage: from sage.functions.other import symbolic_product as sprod sage: r = sprod(x, x, 1, 10); r product(x, x, 1, 10) sage: r.unhold() 3628800 """ def __init__(self): """ EXAMPLES::
sage: from sage.functions.other import symbolic_product as sprod sage: _ = var('m n', domain='integer') sage: r = maxima(sprod(sin(m), m, 1, n)).sage(); r product(sin(m), m, 1, n) sage: isinstance(r.operator(), sage.functions.other.Function_prod) True sage: r = sympy(sprod(sin(m), m, 1, n)).sage(); r # known bug product(sin(m), m, 1, n) sage: isinstance(r.operator(), ....: sage.functions.other.Function_prod) # known bug True sage: giac(sprod(m, m, 1, n)) n! """ BuiltinFunction.__init__(self, "product", nargs=4, conversions=dict(maxima='product', sympy='Product', giac='product'))
def _print_latex_(self, x, var, a, b): r""" EXAMPLES::
sage: from sage.functions.other import symbolic_product as sprod sage: latex(sprod(x^2, x, 1, 10)) {\prod_{x=1}^{10} x^{2}} """ latex(b), latex(x))
symbolic_product = Function_prod()
class Function_limit(BuiltinFunction): """ Placeholder symbolic limit function that is only accessible internally.
This function is called to create formal wrappers of limits that Maxima can't compute::
sage: a = lim(exp(x^2)*(1-erf(x)), x=infinity); a -limit((erf(x) - 1)*e^(x^2), x, +Infinity)
EXAMPLES::
sage: from sage.functions.other import symbolic_limit as slimit sage: slimit(1/x, x, +oo) limit(1/x, x, +Infinity) sage: var('minus,plus') (minus, plus) sage: slimit(1/x, x, +oo) limit(1/x, x, +Infinity) sage: slimit(1/x, x, 0, plus) limit(1/x, x, 0, plus) sage: slimit(1/x, x, 0, minus) limit(1/x, x, 0, minus) """ def __init__(self): """ EXAMPLES::
sage: from sage.functions.other import symbolic_limit as slimit sage: maxima(slimit(1/x, x, +oo)) 0 """ BuiltinFunction.__init__(self, "limit", nargs=0, conversions=dict(maxima='limit'))
def _latex_(self): r""" EXAMPLES::
sage: from sage.functions.other import symbolic_limit as slimit sage: latex(slimit) \lim """
def _print_latex_(self, ex, var, to, direction=''): r""" EXAMPLES::
sage: from sage.functions.other import symbolic_limit as slimit sage: var('x,a') (x, a) sage: f = function('f') sage: latex(slimit(f(x), x, a)) \lim_{x \to a}\, f\left(x\right) sage: latex(limit(f(x), x=oo)) \lim_{x \to +\infty}\, f\left(x\right)
TESTS:
When one-sided limits are converted back from maxima, the direction argument becomes a symbolic variable. We check if typesetting these works::
sage: from sage.functions.other import symbolic_limit as slimit sage: var('minus,plus') (minus, plus) sage: latex(slimit(f(x), x, a, minus)) \lim_{x \to a^-}\, f\left(x\right) sage: latex(slimit(f(x), x, a, plus)) \lim_{x \to a^+}\, f\left(x\right) sage: latex(limit(f(x),x=a,dir='+')) \lim_{x \to a^+}\, f\left(x\right) sage: latex(limit(f(x),x=a,dir='right')) \lim_{x \to a^+}\, f\left(x\right) sage: latex(limit(f(x),x=a,dir='-')) \lim_{x \to a^-}\, f\left(x\right) sage: latex(limit(f(x),x=a,dir='left')) \lim_{x \to a^-}\, f\left(x\right)
Check if :trac:`13181` is fixed::
sage: t = var('t') sage: latex(limit(exp_integral_e(1/2, I*t - I*x)*sqrt(-t + x),t=x,dir='-')) \lim_{t \to x^-}\, \sqrt{-t + x} exp_integral_e\left(\frac{1}{2}, i \, t - i \, x\right) sage: latex(limit(exp_integral_e(1/2, I*t - I*x)*sqrt(-t + x),t=x,dir='+')) \lim_{t \to x^+}\, \sqrt{-t + x} exp_integral_e\left(\frac{1}{2}, i \, t - i \, x\right) sage: latex(limit(exp_integral_e(1/2, I*t - I*x)*sqrt(-t + x),t=x)) \lim_{t \to x}\, \sqrt{-t + x} exp_integral_e\left(\frac{1}{2}, i \, t - i \, x\right) """ else: latex(to), dir_str, latex(ex))
symbolic_limit = Function_limit()
class Function_cases(GinacFunction): """ Formal function holding ``(condition, expression)`` pairs.
Numbers are considered conditions with zero being ``False``. A true condition marks a default value. The function is not evaluated as long as it contains a relation that cannot be decided by Pynac.
EXAMPLES::
sage: ex = cases([(x==0, pi), (True, 0)]); ex cases(((x == 0, pi), (1, 0))) sage: ex.subs(x==0) pi sage: ex.subs(x==2) 0 sage: ex + 1 cases(((x == 0, pi), (1, 0))) + 1 sage: _.subs(x==0) pi + 1
The first encountered default is used, as well as the first relation that can be trivially decided::
sage: cases(((True, pi), (True, 0))) pi
sage: _ = var('y') sage: ex = cases(((x==0, pi), (y==1, 0))); ex cases(((x == 0, pi), (y == 1, 0))) sage: ex.subs(x==0) pi sage: ex.subs(x==0, y==1) pi """ def __init__(self): """ EXAMPLES::
sage: loads(dumps(cases)) cases """
def __call__(self, l, **kwargs): """ EXAMPLES::
sage: ex = cases([(x==0, pi), (True, 0)]); ex cases(((x == 0, pi), (1, 0)))
TESTS::
sage: cases() Traceback (most recent call last): ... TypeError: __call__() takes exactly 2 arguments (1 given)
sage: cases(x) Traceback (most recent call last): ... RuntimeError: cases argument not a sequence """ SR._force_pyobject(l), **kwargs)
def _print_latex_(self, l, **kwargs): r""" EXAMPLES::
sage: ex = cases([(x==0, pi), (True, 0)]); ex cases(((x == 0, pi), (1, 0))) sage: latex(ex) \begin{cases}{\pi} & {x = 0}\\{0} & {1}\end{cases} """ raise ValueError("cases() argument must be a list") else: right = pair
def _sympy_(self, l): """ Convert this cases expression to its SymPy equivalent.
EXAMPLES::
sage: ex = cases(((x<0, pi), (x==1, 1), (True, 0))) sage: assert ex == ex._sympy_()._sage_() """ else:
cases = Function_cases()
class Function_crootof(BuiltinFunction): """ Formal function holding ``(polynomial, index)`` pairs.
The expression evaluates to a floating point value that is an approximation to a specific complex root of the polynomial. The ordering is fixed so you always get the same root.
The functionality is imported from SymPy, see http://docs.sympy.org/latest/_modules/sympy/polys/rootoftools.html
EXAMPLES::
sage: c = complex_root_of(x^6 + x + 1, 1); c complex_root_of(x^6 + x + 1, 1) sage: c.n() -0.790667188814418 + 0.300506920309552*I sage: c.n(100) -0.79066718881441764449859281847 + 0.30050692030955162512001002521*I sage: (c^6 + c + 1).n(100) < 1e-25 True """ def __init__(self): """ EXAMPLES::
sage: loads(dumps(complex_root_of)) complex_root_of """ conversions=dict(sympy='CRootOf'), evalf_params_first=False)
def _eval_(self, poly, index): """ TESTS::
sage: _ = var('y') sage: complex_root_of(1, 1) Traceback (most recent call last): ... ValueError: polynomial in one variable required sage: complex_root_of(x+y, 1) Traceback (most recent call last): ... ValueError: polynomial in one variable required sage: complex_root_of(sin(x), 1) Traceback (most recent call last): ... ValueError: polynomial in one variable required """
def _evalf_(self, poly, index, parent=None, algorithm=None): """ EXAMPLES::
sage: complex_root_of(x^2-2, 1).n() 1.41421356237309 sage: complex_root_of(x^2-2, 3).n() Traceback (most recent call last): ... IndexError: root index out of [-2, 1] range, got 3
TESTS:
Check that low precision is handled (:trac:`24378`)::
sage: complex_root_of(x^8-1, 7).n(2) 0.75 + 0.75*I sage: complex_root_of(x^8-1, 7).n(20) 0.70711 + 0.70711*I """ except AttributeError: prec = 53
complex_root_of = Function_crootof()
|