Ticket #7748: trac_7748-exp_integral.patch

File trac_7748-exp_integral.patch, 7.5 KB (added by fstan, 12 years ago)

Make Ei symbolic.

  • sage/functions/transcendental.py

    # HG changeset patch
    # User Flavia Stan <flavia.stan@gmail.com>
    # Date 1265541742 -3600
    # Node ID 76deac46abf330fa30d2ec1eb6734acaa93f079b
    # Parent  e634615fef0a8dc50ab2857b71bd3c03e069ae53
    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
    2831
    2932from sage.rings.all import (is_RealNumber, RealField,
    3033                            is_ComplexNumber, ComplexField,
    3134                            ZZ, RR, RDF, CDF, prime_range)
    3235                           
    33 from sage.symbolic.function import BuiltinFunction, SR
     36from sage.symbolic.function import BuiltinFunction, SR, is_inexact
    3437
    3538import sage.plot.all
    3639
     
    210213        return R(0.5)
    211214   
    212215    return (s/2 + 1).gamma()   *    (s-1)   * (R.pi()**(-s/2))  *  s.zeta()
    213    
    214216
    215217##     # Use PARI on complex nubmer
    216218##     prec = s.prec()
     
    230232#   return real_field.RealField(prec).pi()
    231233
    232234
    233 def Ei(z, prec=None):
    234     """
    235     Return the value of the complex exponential integral Ei(z) at a
    236     complex number z.
     235class Function_exp_integral(BuiltinFunction):
     236    def __init__(self):
     237        """
     238        Return the value of the complex exponential integral Ei(z) at a
     239        complex number z.
    237240       
    238     EXAMPLES::
     241        EXAMPLES::
     242
     243            sage: Ei(10)
     244            Ei(10)
     245            sage: Ei(I)
     246            Ei(I)
     247            sage: Ei(3+I)
     248            Ei(I + 3)
     249            sage: Ei(1.3)
     250            2.72139888023202
     251           
     252        The branch cut for this function is along the negative real axis::
    239253   
    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
     254            sage: Ei(-3 + 0.1*I)
     255            -0.0129379427181693 + 3.13993830250942*I
     256            sage: Ei(-3 - 0.1*I)
     257            -0.0129379427181693 - 3.13993830250942*I
    248258   
    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:
     259        ALGORITHM: Uses mpmath.
     260        """
     261        BuiltinFunction.__init__(self, "Ei")
     262
     263    def _eval_(self, x ):
     264        """
     265        EXAMPLES::
     266
     267            sage: Ei(10)
     268            Ei(10)
     269            sage: Ei(I)
     270            Ei(I)
     271            sage: Ei(1.3)
     272            2.72139888023202
     273            sage: Ei(10r)
     274            Ei(10)
     275            sage: Ei(1.3r)
     276            2.72139888023202
     277        """
     278        if not isinstance(x, Expression) and is_inexact(x):
     279            return self._evalf_(x, parent(x))
     280        return None
     281           
     282    def _evalf_(self, x, parent=None):
     283        """
     284        EXAMPLES::
     285
     286            sage: Ei(10).n()
     287            2492.22897624188
     288            sage: Ei(20).n()
     289            2.56156526640566e7
     290            sage: Ei(I).n()
     291            0.337403922900968 + 2.51687939716208*I
     292            sage: Ei(3+I).n()
     293            7.82313467600158 + 6.09751978399231*I
     294        """
     295        import mpmath
     296        if isinstance(parent, Parent) and hasattr(parent, 'prec'):
     297            prec = parent.prec()
     298        else:
    262299            prec = 53
     300        return mpmath_utils.call(mpmath.ei, x, prec=prec)
     301
     302    def __call__(self, x, prec=None, coerce=True, hold=False ):
     303        """
     304        Note that the ``prec`` argument is deprecated. The precision for
     305        the result is deduced from the precision of the input. Convert
     306        the input to a higher precision explicitly if a result with higher
     307        precision is desired.
     308
     309        EXAMPLES::
     310
     311            sage: t = Ei(RealField(100)(2.5)); t
     312            7.0737658945786007119235519625
     313            sage: t.prec()
     314            100
     315
     316            sage: Ei(1.1, prec=300)
     317            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.
     318            2.16737827956340306615064476647912607220394065907142504328679588538509331805598360907980986
     319        """
     320        if prec is not None:
     321            from sage.misc.misc import deprecation
     322            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.")
    263323           
    264     import sage.libs.mpmath.all as mp
    265     return mp.call(mp.ei, z, prec=prec)
     324            import mpmath
     325            return mpmath_utils.call(mpmath.ei, x, prec=prec)
     326
     327        return BuiltinFunction.__call__(self, x, coerce=coerce, hold=hold)
     328
     329Ei = Function_exp_integral()
     330
    266331
    267332def Li(x, eps_rel=None, err_bound=False):
    268333    r"""
  • sage/symbolic/function.pyx

    diff --git a/sage/symbolic/function.pyx b/sage/symbolic/function.pyx
    a b  
    11671166        return None
    11681167    return unpickle_function(p)
    11691168
     1169def is_inexact(x):
     1170    """
     1171    Returns True if the argument is an inexact object.
     1172
     1173    TESTS::
     1174
     1175        sage: from sage.symbolic.function import is_inexact
     1176        sage: is_inexact(5)
     1177        False
     1178        sage: is_inexact(5.)
     1179        True
     1180        sage: is_inexact(pi)
     1181        True
     1182        sage: is_inexact(5r)
     1183        False
     1184        sage: is_inexact(5.4r)
     1185        True
     1186    """
     1187    if isinstance(x, (float, complex)):
     1188        return True
     1189    if isinstance(x, Element):
     1190        return not (<Element>x)._parent.is_exact()
     1191    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         sinh(sinh(-coth(v2)/erf(-(0.615863165633 + 0.879368031485*I)*v1^2*v3) - gamma(pi) + csch(-(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)*arctan2(pi, arccot(pi))))
     205        sinh(arcsech(-heaviside(v2)/erf(-(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))/dilog(-(0.0263902659909 + 0.153261789843*I)*arctan2(pi, arccot(pi))))
    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]