Ticket #7748: trac_7748-exp_integral_ver2.4.3.3.alpha1.patch

File trac_7748-exp_integral_ver2.4.3.3.alpha1.patch, 7.9 KB (added by burcin, 12 years ago)

rebased to 4.3.3.alpha1

  • sage/functions/transcendental.py

    # HG changeset patch
    # User Flavia Stan <flavia.stan@gmail.com>
    # Date 1266276244 -3600
    # Node ID a2f3ef9bff74d59da1629398f19da126d7beb5a9
    # Parent  8a4c49d44fa35e2cfa1ecaf6d02d821451205115
    Trac 7748: Make the exponential integral function Ei symbolic.
    
    diff --git a/sage/functions/transcendental.py b/sage/functions/transcendental.py
    a b  
    1818#*****************************************************************************
    1919
    2020import sys
    21 
     21from sage.libs.mpmath import utils as mpmath_utils
    2222import  sage.libs.pari.all
    2323from sage.libs.pari.all import pari, PariError
    2424import sage.rings.complex_field as complex_field
    2525import sage.rings.real_double as real_double
    2626import sage.rings.complex_number
    2727from sage.gsl.integration import numerical_integral
     28from sage.structure.parent import Parent
     29from sage.structure.coerce import parent
     30from sage.symbolic.expression import Expression
     31from sage.functions.log import exp
    2832
    2933from sage.rings.all import (is_RealNumber, RealField,
    3034                            is_ComplexNumber, ComplexField,
    3135                            ZZ, RR, RDF, CDF, prime_range)
    3236                           
    33 from sage.symbolic.function import BuiltinFunction, SR
     37from sage.symbolic.function import BuiltinFunction, SR, is_inexact
    3438
    3539import sage.plot.all
    3640
     
    210214        return R(0.5)
    211215   
    212216    return (s/2 + 1).gamma()   *    (s-1)   * (R.pi()**(-s/2))  *  s.zeta()
    213    
     217
    214218
    215219##     # Use PARI on complex nubmer
    216220##     prec = s.prec()
     
    230234#   return real_field.RealField(prec).pi()
    231235
    232236
    233 def Ei(z, prec=None):
    234     """
    235     Return the value of the complex exponential integral Ei(z) at a
    236     complex number z.
     237class Function_exp_integral(BuiltinFunction):
     238    def __init__(self):
     239        """
     240        Return the value of the complex exponential integral Ei(z) at a
     241        complex number z.
    237242       
    238     EXAMPLES::
     243        EXAMPLES::
     244
     245            sage: Ei(10)
     246            Ei(10)
     247            sage: Ei(I)
     248            Ei(I)
     249            sage: Ei(3+I)
     250            Ei(I + 3)
     251            sage: Ei(1.3)
     252            2.72139888023202
     253           
     254        The branch cut for this function is along the negative real axis::
    239255   
    240         sage: Ei(10)
    241         2492.22897624188
    242         sage: Ei(20)
    243         2.56156526640566e7
    244         sage: Ei(I)
    245         0.337403922900968 + 2.51687939716208*I
    246         sage: Ei(3+I)
    247         7.82313467600158 + 6.09751978399231*I
     256            sage: Ei(-3 + 0.1*I)
     257            -0.0129379427181693 + 3.13993830250942*I
     258            sage: Ei(-3 - 0.1*I)
     259            -0.0129379427181693 - 3.13993830250942*I
    248260   
    249     The branch cut for this function is along the negative real axis::
    250    
    251         sage: Ei(-3 + 0.1*I)
    252         -0.0129379427181693 + 3.13993830250942*I
    253         sage: Ei(-3 - 0.1*I)
    254         -0.0129379427181693 - 3.13993830250942*I
    255    
    256     ALGORITHM: Uses mpmath.
    257     """
    258     if prec is None:
    259         try:
    260             prec = z.prec()
    261         except AttributeError:
     261        ALGORITHM: Uses mpmath.
     262        """
     263        BuiltinFunction.__init__(self, "Ei")
     264
     265    def _eval_(self, x ):
     266        """
     267        EXAMPLES::
     268
     269            sage: Ei(10)
     270            Ei(10)
     271            sage: Ei(I)
     272            Ei(I)
     273            sage: Ei(1.3)
     274            2.72139888023202
     275            sage: Ei(10r)
     276            Ei(10)
     277            sage: Ei(1.3r)
     278            2.72139888023202
     279        """
     280        if not isinstance(x, Expression) and is_inexact(x):
     281            return self._evalf_(x, parent(x))
     282        return None
     283           
     284    def _evalf_(self, x, parent=None):
     285        """
     286        EXAMPLES::
     287
     288            sage: Ei(10).n()
     289            2492.22897624188
     290            sage: Ei(20).n()
     291            2.56156526640566e7
     292            sage: Ei(I).n()
     293            0.337403922900968 + 2.51687939716208*I
     294            sage: Ei(3+I).n()
     295            7.82313467600158 + 6.09751978399231*I
     296        """
     297        import mpmath
     298        if isinstance(parent, Parent) and hasattr(parent, 'prec'):
     299            prec = parent.prec()
     300        else:
    262301            prec = 53
     302        return mpmath_utils.call(mpmath.ei, x, prec=prec)
     303
     304    def __call__(self, x, prec=None, coerce=True, hold=False ):
     305        """
     306        Note that the ``prec`` argument is deprecated. The precision for
     307        the result is deduced from the precision of the input. Convert
     308        the input to a higher precision explicitly if a result with higher
     309        precision is desired.
     310
     311        EXAMPLES::
     312
     313            sage: t = Ei(RealField(100)(2.5)); t
     314            7.0737658945786007119235519625
     315            sage: t.prec()
     316            100
     317
     318            sage: Ei(1.1, prec=300)
     319            doctest:...: DeprecationWarning: The prec keyword argument is deprecated. Explicitly set the precision of the input, for example Ei(RealField(300)(1)), or use the prec argument to .n() for exact inputs, e.g., Ei(1).n(300), instead.
     320            2.16737827956340306615064476647912607220394065907142504328679588538509331805598360907980986
     321        """
     322        if prec is not None:
     323            from sage.misc.misc import deprecation
     324            deprecation("The prec keyword argument is deprecated. Explicitly set the precision of the input, for example Ei(RealField(300)(1)), or use the prec argument to .n() for exact inputs, e.g., Ei(1).n(300), instead.")
    263325           
    264     import sage.libs.mpmath.all as mp
    265     return mp.call(mp.ei, z, prec=prec)
     326            import mpmath
     327            return mpmath_utils.call(mpmath.ei, x, prec=prec)
     328
     329        return BuiltinFunction.__call__(self, x, coerce=coerce, hold=hold)
     330
     331    def _derivative_(self, x, diff_param=None):
     332        """
     333        EXAMPLES::
     334       
     335            sage: Ei(x).diff(x)
     336            e^x/x
     337            sage: Ei(x).diff(x).subs(x=1)
     338            e
     339            sage: Ei(x^2).diff(x)
     340            2*e^(x^2)/x
     341            sage: f = function('f')
     342            sage: Ei(f(x)).diff(x)
     343            e^f(x)*D[0](f)(x)/f(x)
     344        """
     345        return exp(x)/x
     346
     347Ei = Function_exp_integral()
     348
    266349
    267350def Li(x, eps_rel=None, err_bound=False):
    268351    r"""
  • sage/symbolic/function.pyx

    diff --git a/sage/symbolic/function.pyx b/sage/symbolic/function.pyx
    a b  
    12191219        return None
    12201220    return unpickle_function(p)
    12211221
     1222def is_inexact(x):
     1223    """
     1224    Returns True if the argument is an inexact object.
     1225
     1226    TESTS::
     1227
     1228        sage: from sage.symbolic.function import is_inexact
     1229        sage: is_inexact(5)
     1230        False
     1231        sage: is_inexact(5.)
     1232        True
     1233        sage: is_inexact(pi)
     1234        True
     1235        sage: is_inexact(5r)
     1236        False
     1237        sage: is_inexact(5.4r)
     1238        True
     1239    """
     1240    if isinstance(x, (float, complex)):
     1241        return True
     1242    if isinstance(x, Element):
     1243        return not (<Element>x)._parent.is_exact()
     1244    return False
  • sage/symbolic/random_tests.py

    diff --git a/sage/symbolic/random_tests.py b/sage/symbolic/random_tests.py
    a b  
    202202
    203203        sage: from sage.symbolic.random_tests import *
    204204        sage: random_expr(50, nvars=3, coeff_generator=CDF.random_element)
    205         arctanh(sinh(-arcsech(v2)/csc((-0.615863165633 + 0.879368031485*I)*v1^2*v3) - gamma(pi) + erf((-0.708874026302 - 0.954135400334*I)*v3)))^arcsech(-cosh(-polylog((v2 + 0.913564344312 + 0.0898040160336*I)^((-0.723896589334 - 0.799038508886*I)*v2), -v1 - v3))/sgn((-0.0263902659909 + 0.153261789843*I)*arctan2(pi, arccot(pi))))
     205        sinh(sinh(-coth(v2)/csc((-0.615863165633 + 0.879368031485*I)*v1^2*v3) - gamma(pi) + erf((-0.708874026302 - 0.954135400334*I)*v3)))^coth(-cosh(-polylog((v2 + 0.913564344312 + 0.0898040160336*I)^((-0.723896589334 - 0.799038508886*I)*v2), -v1 - v3))/arcsin((-0.0263902659909 + 0.153261789843*I)*cosh(pi*catalan)))
    206206        sage: random_expr(5, verbose=True)
    207207        About to apply <built-in function add> to [v1, v1]
    208208        About to apply <built-in function div> to [-1/3, 2*v1]