Ticket #11143: trac_11143.patch

File trac_11143.patch, 53.7 KB (added by benjaminfjones, 10 years ago)

adds sage/functions/exp_integral.py

  • doc/en/reference/functions.rst

    # HG changeset patch
    # User Benjamin Jones <benjaminfjones@gmail.com>
    # Date 1314069403 25200
    # Node ID 63e35360db8556236303e1c9355b6ca16d25e4c8
    # Parent  dacff6345906c5289fc9677daa93a93764ac6ee8
    Trac 11143: added exp_integral_e, exp_integral_e1, and moved other exponential integrals to new file sage/functions/exp_integral.py
    
    diff --git a/doc/en/reference/functions.rst b/doc/en/reference/functions.rst
    a b  
    1010   sage/functions/piecewise
    1111   sage/functions/orthogonal_polys
    1212   sage/functions/special
     13   sage/functions/exp_integral
    1314   sage/functions/wigner
    1415   sage/functions/generalized
    1516   sage/functions/prime_pi
     17 No newline at end of file
  • sage/functions/all.py

    diff --git a/sage/functions/all.py b/sage/functions/all.py
    a b  
    2424from log import (exp, log, ln, polylog, dilog)
    2525
    2626
    27 from transcendental import (exponential_integral_1,
    28                             zeta, zetaderiv, zeta_symmetric,
    29                             Li, Ei,
    30                             dickman_rho)
     27from transcendental import (zeta, zetaderiv, zeta_symmetric,
     28                            Li, dickman_rho)
    3129
    3230from special import (bessel_I, bessel_J, bessel_K, bessel_Y,
    3331                     hypergeometric_U, Bessel,
     
    3533                     spherical_hankel1, spherical_hankel2,
    3634                     spherical_harmonic, jacobi,
    3735                     inverse_jacobi, log_gamma,
    38                      lngamma, exp_int, error_fcn, elliptic_e,
     36                     lngamma, error_fcn, elliptic_e,
    3937                     elliptic_f, elliptic_ec, elliptic_eu,
    4038                     elliptic_kc, elliptic_pi, elliptic_j,
    4139                     airy_ai, airy_bi)
     
    6462                         kronecker_delta)
    6563
    6664from min_max import max_symbolic, min_symbolic
     65
     66from exp_integral import (exp_integral_e, exp_integral_e1, exp_integral_li,
     67                          exp_integral_si, exp_integral_ci,
     68                          exp_integral_shi, exp_integral_chi,
     69                          exponential_integral_1, exp_int, Ei)
  • new file sage/functions/exp_integral.py

    diff --git a/sage/functions/exp_integral.py b/sage/functions/exp_integral.py
    new file mode 100644
    - +  
     1r"""
     2Exponential Integrals
     3
     4AUTHORS:
     5
     6- Benjamin Jones (2011-06-12)
     7
     8This module provides easy access to many exponential integral
     9special functions. It utilizes Maxima's `special functions package`_ and
     10the `mpmath library`_.
     11
     12REFERENCES:
     13
     14- [AS]_ Abramowitz and Stegun: *Handbook of Mathematical Functions*
     15- Wikipedia Entry: http://en.wikipedia.org/wiki/Exponential_integral
     16- Online Encyclopedia of Special Function: http://algo.inria.fr/esf/index.html
     17- NIST Digital Library of Mathematical Functions: http://dlmf.nist.gov/
     18- Maxima `special functions package`_
     19- `mpmath library`_
     20
     21.. [AS] 'Handbook of Mathematical Functions', Milton Abramowitz and Irene
     22   A. Stegun, National Bureau of Standards Applied Mathematics Series, 55.
     23   See also http://www.math.sfu.ca/~cbm/aands/.
     24.. _`special functions package`: http://maxima.sourceforge.net/docs/manual/en/maxima_15.html
     25.. _`mpmath library`: http://code.google.com/p/mpmath/
     26
     27AUTHORS:
     28
     29- Benjamin Jones
     30
     31    Implementations of the classes ``Function_exp_integral_*``.
     32
     33- David Joyner and William Stein
     34
     35    Authors of the code which was moved from special.py and trans.py.
     36    Implementation of :meth:`exp_int` (from sage/functions/special.py).
     37    Implementation of :meth:`exponential_integral_1` (from
     38    sage/functions/transcendental.py).
     39
     40"""
     41
     42#*****************************************************************************
     43#       Copyright (C) 2011 Benjamin Jones <benjaminfjones@gmail.com>
     44#
     45#  Distributed under the terms of the GNU General Public License (GPL)
     46#
     47#    This code is distributed in the hope that it will be useful,
     48#    but WITHOUT ANY WARRANTY; without even the implied warranty of
     49#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     50#    General Public License for more details.
     51#
     52#  The full text of the GPL is available at:
     53#
     54#                  http://www.gnu.org/licenses/
     55#*****************************************************************************
     56
     57import sage.interfaces.all
     58from sage.misc.sage_eval import sage_eval
     59from sage.symbolic.function import BuiltinFunction, is_inexact
     60from sage.calculus.calculus import maxima
     61from sage.symbolic.expression import Expression
     62from sage.structure.parent import Parent
     63from sage.structure.coerce import parent
     64from sage.libs.mpmath import utils as mpmath_utils
     65mpmath_utils_call = mpmath_utils.call # eliminate some overhead in _evalf_
     66
     67from sage.rings.rational_field import RationalField
     68from sage.rings.real_mpfr import RealField
     69from sage.rings.complex_field import ComplexField
     70from sage.rings.all import ZZ, QQ, RR, RDF
     71from sage.functions.log import exp, log
     72from sage.functions.trig import sin, cos
     73from sage.functions.hyperbolic import sinh, cosh
     74
     75
     76class Function_exp_integral_e(BuiltinFunction):
     77    r"""
     78    The generalized complex exponential integral `E_n(z)` defined by
     79
     80    .. math::
     81
     82        \operatorname{E_n}(z) = \int_1^{\infty} \frac{e^{-z t}}{t^n} \; dt
     83
     84    for complex numbers `n` and `z`, see [AS]_ 5.1.4.
     85
     86    The special case where `n = 1` is denoted in Sage by
     87    ``exp_integral_e1``.
     88
     89    EXAMPLES:
     90
     91    Numerical evaluation is handled using mpmath::
     92
     93        sage: N(exp_integral_e(1,1))
     94        0.219383934395520
     95        sage: exp_integral_e(1, RealField(100)(1))
     96        0.21938393439552027367716377546
     97
     98    We can compare this to PARI's evaluation of
     99    :meth:`exponential_integral_1`::
     100
     101        sage: N(exponential_integral_1(1))
     102        0.219383934395520
     103
     104    We can verify one case of [AS]_ 5.1.45, i.e.
     105    `E_n(z) = z^{n-1}\Gamma(1-n,z)`::
     106
     107        sage: N(exp_integral_e(2, 3+I))
     108        0.00354575823814662 - 0.00973200528288687*I
     109        sage: N((3+I)*gamma(-1, 3+I))
     110        0.00354575823814662 - 0.00973200528288687*I
     111
     112    Maxima returns the following improper integral as a multiple of
     113    ``exp_integral_e(1,1)``::
     114
     115        sage: uu = integral(e^(-x)*log(x+1),x,0,oo)
     116        sage: uu
     117        e*exp_integral_e(1, 1)
     118        sage: uu.n(digits=30)
     119        0.596347362323194074341078499369
     120
     121    Symbolic derivatives and integrals are handled by Sage and Maxima::
     122
     123        sage: x = var('x')
     124        sage: f = exp_integral_e(2,x)
     125        sage: f.diff(x)
     126        -exp_integral_e(1, x)
     127
     128        sage: f.integrate(x)
     129        -exp_integral_e(3, x)
     130
     131        sage: f = exp_integral_e(-1,x)
     132        sage: f.integrate(x)
     133        Ei(-x) - gamma(-1, x)
     134
     135    Some special values of ``exp_integral_e`` can be simplified.
     136    [AS]_ 5.1.23::
     137
     138        sage: f = exp_integral_e(0,x)
     139        sage: f.simplify()
     140        e^(-x)/x
     141
     142    [AS]_ 5.1.24::
     143
     144        sage: nn = var('nn')
     145        sage: assume(nn > 1)
     146        sage: f = exp_integral_e(nn,0)
     147        sage: f.simplify()
     148        1/(nn - 1)
     149
     150    ALGORITHM:
     151
     152    Numerical evaluation is handled using mpmath, but symbolics are handled
     153    by Sage and Maxima.
     154
     155    """
     156    def __init__(self):
     157        """
     158        See the docstring for :meth:`Function_exp_integral_e`.
     159
     160        EXAMPLES::
     161
     162            sage: exp_integral_e(1,0)
     163            exp_integral_e(1, 0)
     164
     165        """
     166        BuiltinFunction.__init__(self, "exp_integral_e", nargs=2, latex_name=r'exp_integral_e',
     167                                 conversions=dict(maxima='expintegral_e'))
     168
     169    def _eval_(self, n, z):
     170        """
     171        EXAMPLES::
     172
     173            sage: exp_integral_e(1.0, x)
     174            exp_integral_e(1.00000000000000, x)
     175            sage: exp_integral_e(x, 1.0)
     176            exp_integral_e(x, 1.00000000000000)
     177            sage: exp_integral_e(1.0, 1.0)
     178            0.219383934395520
     179
     180        """
     181        if not isinstance(n, Expression) and not isinstance(z, Expression) and \
     182               (is_inexact(n) or is_inexact(z)):
     183            coercion_model = sage.structure.element.get_coercion_model()
     184            n, z = coercion_model.canonical_coercion(n, z)
     185            return self._evalf_(n, z, parent(n))
     186
     187        z_zero = False
     188        # special case: z == 0 and n > 1
     189        if isinstance(z, Expression):
     190            if z._is_numerically_zero():
     191                z_zero = True # for later
     192                if n > 1:
     193                    return 1/(n-1)
     194        else:
     195            if not z:
     196                z_zero = True
     197                if n > 1:
     198                    return 1/(n-1)
     199
     200        # special case: n == 0
     201        if isinstance(n, Expression):
     202            if n._is_numerically_zero():
     203                if z_zero:
     204                    return None
     205                else:
     206                    return exp(-z)/z
     207        else:
     208            if not n:
     209                if z_zero:
     210                    return None
     211                else:
     212                    return exp(-z)/z
     213
     214        return None # leaves the expression unevaluated
     215
     216    def _evalf_(self, n, z, parent=None):
     217        """
     218        EXAMPLES::
     219
     220            sage: N(exp_integral_e(1, 1+I))
     221            0.000281624451981418 - 0.179324535039359*I
     222            sage: exp_integral_e(1, RealField(100)(1))
     223            0.21938393439552027367716377546
     224
     225        """
     226        import mpmath
     227        return mpmath_utils.call(mpmath.expint, n, z, parent=parent)
     228
     229    def _derivative_(self, n, z, diff_param=None):
     230        """
     231        If `n` is an integer strictly larger than 0, then the derivative of
     232        `E_n(z)` with respect to `z` is
     233        `-E_{n-1}(z)`. See [AS]_ 5.1.26.
     234
     235        EXAMPLES::
     236
     237            sage: x = var('x')
     238            sage: f = exp_integral_e(2,x)
     239            sage: f.diff(x)
     240            -exp_integral_e(1, x)
     241
     242            sage: f = exp_integral_e(2,sqrt(x))
     243            sage: f.diff(x)
     244            -1/2*exp_integral_e(1, sqrt(x))/sqrt(x)
     245
     246        """
     247        if n in ZZ and n > 0:
     248            return -1*exp_integral_e(n-1,z)
     249        else:
     250            raise NotImplementedError("The derivative of this function is only implemented for n = 1, 2, 3, ...")
     251
     252exp_integral_e = Function_exp_integral_e()
     253
     254
     255class Function_exp_integral_e1(BuiltinFunction):
     256    r"""
     257    The generalized complex exponential integral `E_1(z)` defined by
     258
     259    .. math::
     260
     261        \operatorname{E_1}(z) = \int_z^\infty \frac{e^{-t}}{t}\; dt
     262
     263    see [AS]_ 5.1.4.
     264
     265    EXAMPLES:
     266
     267    Numerical evaluation is handled using mpmath::
     268
     269        sage: N(exp_integral_e1(1))
     270        0.219383934395520
     271        sage: exp_integral_e1(RealField(100)(1))
     272        0.21938393439552027367716377546
     273
     274    We can compare this to PARI's evaluation of
     275    :meth:`exponential_integral_1`::
     276
     277        sage: N(exp_integral_e1(2.0))
     278        0.0489005107080611
     279        sage: N(exponential_integral_1(2.0))
     280        0.0489005107080611
     281
     282    Symbolic derivatives and integrals are handled by Sage and Maxima::
     283
     284        sage: x = var('x')
     285        sage: f = exp_integral_e1(x)
     286        sage: f.diff(x)
     287        -e^(-x)/x
     288
     289        sage: f.integrate(x)
     290        -exp_integral_e(2, x)
     291
     292    ALGORITHM:
     293
     294    Numerical evaluation is handled using mpmath, but symbolics are handled
     295    by Sage and Maxima.
     296
     297    """
     298    def __init__(self):
     299        """
     300        See the docstring for :class:`Function_exp_integral_e1`.
     301
     302        EXAMPLES::
     303
     304            sage: exp_integral_e1(1)
     305            exp_integral_e1(1)
     306
     307        """
     308        BuiltinFunction.__init__(self, "exp_integral_e1", nargs=1, latex_name=r'exp_integral_e1', conversions=dict(maxima='expintegral_e1'))
     309
     310    def _eval_(self, z):
     311        """
     312        EXAMPLES::
     313
     314            sage: exp_integral_e1(x)
     315            exp_integral_e1(x)
     316            sage: exp_integral_e1(1.0)
     317            0.219383934395520
     318
     319        """
     320        if not isinstance(z, Expression) and is_inexact(z):
     321            return self._evalf_(z, parent(z))
     322
     323        return None # leaves the expression unevaluated
     324
     325    def _evalf_(self, z, parent=None):
     326        """
     327        EXAMPLES::
     328
     329            sage: N(exp_integral_e1(1+I))
     330            0.000281624451981418 - 0.179324535039359*I
     331            sage: exp_integral_e1(RealField(200)(0.5))
     332            0.55977359477616081174679593931508523522684689031635351524829
     333
     334        """
     335        import mpmath
     336        return mpmath_utils_call(mpmath.e1, z, parent=parent)
     337
     338    def _derivative_(self, z, diff_param=None):
     339        """
     340        The derivative of `E_1(z)` is `-e^{-z}/z`. See [AS], 5.1.26.
     341
     342        EXAMPLES::
     343
     344            sage: x = var('x')
     345            sage: f = exp_integral_e1(x)
     346            sage: f.diff(x)
     347            -e^(-x)/x
     348
     349            sage: f = exp_integral_e1(x^2)
     350            sage: f.diff(x)
     351            -2*e^(-x^2)/x
     352
     353        """
     354        return -exp(-z)/z
     355
     356exp_integral_e1 = Function_exp_integral_e1()
     357
     358
     359class Function_exp_integral_li(BuiltinFunction):
     360    r"""
     361    The logarithmic integral `\operatorname{li}(z)` defined by
     362
     363    .. math::
     364
     365        \operatorname{li}(x) = \int_0^z \frac{dt}{\ln(t)} = \operatorname{Ei}(\ln(x))
     366
     367    for x > 1 and by analytic continuation for complex arguments z (see [AS]_ 5.1.3).
     368
     369    EXAMPLES:
     370
     371    Numerical evaluation for real and complex arguments is handled using mpmath::
     372
     373        sage: N(exp_integral_li(3))
     374        2.16358859466719
     375        sage: N(exp_integral_li(3), digits=30)
     376        2.16358859466719197287692236735
     377        sage: exp_integral_li(ComplexField(100)(3+I))
     378        2.2879892769816826157078450911 + 0.87232935488528370139883806779*I
     379
     380    Symbolic derivatives and integrals are handled by Sage and Maxima::
     381
     382        sage: x = var('x')
     383        sage: f = exp_integral_li(x)
     384        sage: f.diff(x)
     385        1/log(x)
     386
     387        sage: f.integrate(x)
     388        x*exp_integral_li(x) - expintegral_ei(2*log(x))
     389
     390    Here is a test from the mpmath documentation. There are
     391    1,925,320,391,606,803,968,923 many prime numbers less than 1e23. The
     392    value of ``exp_integral_li(1e23)`` is very close to this::
     393
     394        sage: exp_integral_li(1e23)
     395        1.92532039161405e21
     396
     397    ALGORITHM:
     398
     399    Numerical evaluation is handled using mpmath, but symbolics are handled
     400    by Sage and Maxima.
     401
     402    REFERENCES:
     403
     404    - http://en.wikipedia.org/wiki/Logarithmic_integral_function
     405    - mpmath documentation: `logarithmic-integral`_
     406
     407    .. _`logarithmic-integral`: http://mpmath.googlecode.com/svn/trunk/doc/build/functions/expintegrals.html#logarithmic-integral
     408
     409
     410    """
     411    def __init__(self):
     412        """
     413        See the docstring for ``Function_exp_integral_li``.
     414
     415        EXAMPLES::
     416
     417            sage: exp_integral_li(3)
     418            exp_integral_li(3)
     419
     420        """
     421        BuiltinFunction.__init__(self, "exp_integral_li", nargs=1, latex_name=r'exp_integral_li', conversions=dict(maxima='expintegral_li'))
     422
     423    def _eval_(self, z):
     424        """
     425        EXAMPLES::
     426
     427            sage: z = var('z')
     428            sage: exp_integral_li(z)
     429            exp_integral_li(z)
     430            sage: exp_integral_li(3.0)
     431            2.16358859466719
     432
     433        """
     434        if not isinstance(z, Expression) and is_inexact(z):
     435            return self._evalf_(z, parent(z))
     436
     437        return None # leaves the expression unevaluated
     438
     439    def _evalf_(self, z, parent=None):
     440        """
     441        EXAMPLES::
     442
     443            sage: N(exp_integral_li(1e6))
     444            78627.5491594622
     445            sage: exp_integral_li(RealField(200)(1e6))
     446            78627.549159462181919862910747947261161321874382421767074759
     447
     448        """
     449        import mpmath
     450        return mpmath_utils_call(mpmath.li, z, parent=parent)
     451
     452    def _derivative_(self, z, diff_param=None):
     453        """
     454        The derivative of `\operatorname{li}(z) is `1/log(z)`.
     455
     456        EXAMPLES::
     457
     458            sage: x = var('x')
     459            sage: f = exp_integral_li(x)
     460            sage: f.diff(x)
     461            1/log(x)
     462
     463            sage: f = exp_integral_li(x^2)
     464            sage: f.diff(x)
     465            2*x/log(x^2)
     466
     467        """
     468        return 1/log(z)
     469
     470exp_integral_li = Function_exp_integral_li()
     471
     472
     473class Function_exp_integral_si(BuiltinFunction):
     474    r"""
     475    The trigonometric integral `\operatorname{Si}(z)` defined by
     476
     477    .. math::
     478
     479        \operatorname{Si}(z) = \int_0^z \frac{\sin(t)}{t}\; dt,
     480
     481    see [AS]_ 5.2.1.
     482
     483    EXAMPLES:
     484
     485    Numerical evaluation for real and complex arguments is handled using mpmath::
     486
     487        sage: exp_integral_si(0)
     488        0
     489        sage: exp_integral_si(0.0)
     490        0.000000000000000
     491        sage: exp_integral_si(3.0)
     492        1.84865252799947
     493        sage: N(exp_integral_si(3), digits=30)
     494        1.84865252799946825639773025111
     495        sage: exp_integral_si(ComplexField(100)(3+I))
     496        2.0277151656451253616038525998 + 0.015210926166954211913653130271*I
     497
     498    The limit of `\operatorname{Si}(z)` as `z \to \infty` is `\pi/2`::
     499
     500        sage: N(exp_integral_si(1e23))
     501        1.57079632679490
     502        sage: N(pi/2)
     503        1.57079632679490
     504
     505    At 200 bits of precision `\operatorname{Si}(10^{23})` agrees with `\pi/2` up to
     506    `10^{-24}`::
     507
     508        sage: exp_integral_si(RealField(200)(1e23))
     509        1.5707963267948966192313288218697837425815368604836679189519
     510        sage: N(pi/2, prec=200)
     511        1.5707963267948966192313216916397514420985846996875529104875
     512
     513    The exponential sine integral is analytic everywhere::
     514
     515        sage: exp_integral_si(-1.0)
     516        -0.946083070367183
     517        sage: exp_integral_si(-2.0)
     518        -1.60541297680269
     519        sage: exp_integral_si(-1e23)
     520        -1.57079632679490
     521
     522    Symbolic derivatives and integrals are handled by Sage and Maxima::
     523
     524        sage: x = var('x')
     525        sage: f = exp_integral_si(x)
     526        sage: f.diff(x)
     527        sin(x)/x
     528
     529        sage: f.integrate(x)
     530        x*exp_integral_si(x) + cos(x)
     531
     532        sage: integrate(sin(x)/x, x)
     533        1/2*I*Ei(-I*x) - 1/2*I*Ei(I*x)
     534
     535    Compare values of the functions `\operatorname{Si}(x)` and
     536    `f(x) = (1/2)i \cdot \operatorname{Ei}(-ix) - (1/2)i \cdot
     537    \operatorname{Ei}(ix) - \pi/2`, which are both anti-derivatives of
     538    `\sin(x)/x`, at some random positive real numbers::
     539
     540        sage: f(x) = 1/2*I*Ei(-I*x) - 1/2*I*Ei(I*x) - pi/2
     541        sage: g(x) = exp_integral_si(x)
     542        sage: R = [ abs(RDF.random_element()) for i in range(100) ]
     543        sage: all(abs(f(x) - g(x)) < 1e-10 for x in R)
     544        True
     545
     546    The Nielsen spiral is the parametric plot of (Si(t), Ci(t))::
     547
     548        sage: x=var('x')
     549        sage: f(x) = exp_integral_si(x)
     550        sage: g(x) = exp_integral_ci(x)
     551        sage: P = parametric_plot([f, g], (x, 0.5 ,20))
     552        sage: show(P, frame=True, axes=False)
     553
     554    ALGORITHM:
     555
     556    Numerical evaluation is handled using mpmath, but symbolics are handled
     557    by Sage and Maxima.
     558
     559    REFERENCES:
     560
     561    - http://en.wikipedia.org/wiki/Trigonometric_integral
     562    - mpmath documentation: `si`_
     563
     564    .. _`si`: http://mpmath.googlecode.com/svn/trunk/doc/build/functions/expintegrals.html#si
     565
     566    """
     567    def __init__(self):
     568        """
     569        See the docstring for ``Function_exp_integral_si``.
     570
     571        EXAMPLES::
     572
     573            sage: exp_integral_si(1)
     574            exp_integral_si(1)
     575
     576        """
     577        BuiltinFunction.__init__(self, "exp_integral_si", nargs=1, latex_name=r'\operatorname{Si}', conversions=dict(maxima='expintegral_si'))
     578
     579    def _eval_(self, z):
     580        """
     581        EXAMPLES::
     582
     583            sage: z = var('z')
     584            sage: exp_integral_si(z)
     585            exp_integral_si(z)
     586            sage: exp_integral_si(3.0)
     587            1.84865252799947
     588            sage: exp_integral_si(0)
     589            0
     590
     591        """
     592        if not isinstance(z, Expression) and is_inexact(z):
     593            return self._evalf_(z, parent(z))
     594
     595        # special case: z = 0
     596        if isinstance(z, Expression):
     597            if z._is_numerically_zero():
     598                return 0
     599        else:
     600            if not z:
     601                return 0
     602
     603        return None # leaves the expression unevaluated
     604
     605    def _evalf_(self, z, parent=None):
     606        """
     607        EXAMPLES:
     608
     609        The limit `\operatorname{Si}(z)` as `z \to \infty`  is `\pi/2`::
     610
     611            sage: N(exp_integral_si(1e23) - pi/2)
     612            0.000000000000000
     613
     614        At 200 bits of precision `\operatorname{Si}(10^{23})` agrees with `\pi/2` up to
     615        `10^{-24}`::
     616
     617            sage: exp_integral_si(RealField(200)(1e23))
     618            1.5707963267948966192313288218697837425815368604836679189519
     619            sage: N(pi/2, prec=200)
     620            1.5707963267948966192313216916397514420985846996875529104875
     621
     622        The exponential sine integral is analytic everywhere, even on the
     623        negative real axis::
     624
     625            sage: exp_integral_si(-1.0)
     626            -0.946083070367183
     627            sage: exp_integral_si(-2.0)
     628            -1.60541297680269
     629            sage: exp_integral_si(-1e23)
     630            -1.57079632679490
     631
     632        """
     633        import mpmath
     634        return mpmath_utils_call(mpmath.si, z, parent=parent)
     635
     636    def _derivative_(self, z, diff_param=None):
     637        """
     638        The derivative of `\operatorname{Si}(z)` is `\sin(z)/z` if `z` is not zero. The derivative
     639        at `z = 0` is `1` (but this exception is not currently implimented).
     640
     641        EXAMPLES::
     642
     643            sage: x = var('x')
     644            sage: f = exp_integral_si(x)
     645            sage: f.diff(x)
     646            sin(x)/x
     647
     648            sage: f = exp_integral_si(x^2)
     649            sage: f.diff(x)
     650            2*sin(x^2)/x
     651
     652        """
     653        return sin(z)/z
     654
     655exp_integral_si = Function_exp_integral_si()
     656
     657
     658class Function_exp_integral_ci(BuiltinFunction):
     659    r"""
     660    The trigonometric integral `\operatorname{Ci}(z)` defined by
     661
     662    .. math::
     663
     664        \operatorname{Ci}(z) = \gamma + \log(z) + \int_0^z \frac{\cos(t)-1}{t}\; dt,
     665
     666    where `\gamma` is the Euler gamma constant (``euler_gamma`` in Sage),
     667    see [AS]_ 5.2.1.
     668
     669    EXAMPLES:
     670
     671    Numerical evaluation for real and complex arguments is handled using mpmath::
     672
     673        sage: exp_integral_ci(3.0)
     674        0.119629786008000
     675
     676    Compare ``exp_integral_ci(3.0)`` to the definition of the value using
     677    numerical integration::
     678
     679        sage: N(euler_gamma + log(3.0) + integrate((cos(x)-1)/x, x, 0, 3.0) - exp_integral_ci(3.0)) < 1e-14
     680        True
     681
     682    Arbitrary precision and complex arguments are handled::
     683
     684        sage: N(exp_integral_ci(3), digits=30)
     685        0.119629786008000327626472281177
     686        sage: exp_integral_ci(ComplexField(100)(3+I))
     687        0.078134230477495714401983633057 - 0.37814733904787920181190368789*I
     688
     689    The limit `\operatorname{Ci}(z)` as `z \to \infty` is zero::
     690
     691        sage: N(exp_integral_ci(1e23))
     692        -3.24053937643003e-24
     693
     694    Symbolic derivatives and integrals are handled by Sage and Maxima::
     695
     696        sage: x = var('x')
     697        sage: f = exp_integral_ci(x)
     698        sage: f.diff(x)
     699        cos(x)/x
     700
     701        sage: f.integrate(x)
     702        x*exp_integral_ci(x) - sin(x)
     703
     704    The Nielsen spiral is the parametric plot of (Si(t), Ci(t))::
     705
     706        sage: t=var('t')
     707        sage: f(t) = exp_integral_si(t)
     708        sage: g(t) = exp_integral_ci(t)
     709        sage: P = parametric_plot([f, g], (t, 0.5 ,20))
     710        sage: show(P, frame=True, axes=False)
     711
     712    ALGORITHM:
     713
     714    Numerical evaluation is handled using mpmath, but symbolics are handled
     715    by Sage and Maxima.
     716
     717    REFERENCES:
     718
     719    - http://en.wikipedia.org/wiki/Trigonometric_integral
     720    - mpmath documentation: `ci`_
     721
     722    .. _`ci`: http://mpmath.googlecode.com/svn/trunk/doc/build/functions/expintegrals.html#ci
     723
     724    """
     725    def __init__(self):
     726        """
     727        See the docstring for :class:`Function_exp_integral_ci`.
     728
     729        EXAMPLES::
     730
     731            sage: exp_integral_ci(1)
     732            exp_integral_ci(1)
     733
     734        """
     735        BuiltinFunction.__init__(self, "exp_integral_ci", nargs=1, latex_name=r'\operatorname{Ci}', conversions=dict(maxima='expintegral_ci'))
     736
     737    def _eval_(self, z):
     738        """
     739        EXAMPLES::
     740
     741            sage: z = var('z')
     742            sage: exp_integral_ci(z)
     743            exp_integral_ci(z)
     744            sage: exp_integral_ci(3.0)
     745            0.119629786008000
     746            sage: exp_integral_ci(0)
     747            exp_integral_ci(0)
     748            sage: N(exp_integral_ci(0))
     749            -infinity
     750
     751        """
     752        if not isinstance(z, Expression) and is_inexact(z):
     753            return self._evalf_(z, parent(z))
     754
     755        return None # leaves the expression unevaluated
     756
     757    def _evalf_(self, z, parent=None):
     758        """
     759        EXAMPLES::
     760
     761            sage: N(exp_integral_ci(1e23)) < 1e-20
     762            True
     763            sage: N(exp_integral_ci(1e-10), digits=30)
     764            -22.4486352650389235918737540487
     765            sage: exp_integral_ci(ComplexField(100)(I))
     766            0.83786694098020824089467857943 + 1.5707963267948966192313216916*I
     767
     768        """
     769        import mpmath
     770        return mpmath_utils_call(mpmath.ci, z, parent=parent)
     771
     772    def _derivative_(self, z, diff_param=None):
     773        """
     774        The derivative of `\operatorname{Ci}(z)` is `\cos(z)/z` if `z` is not zero.
     775
     776        EXAMPLES::
     777
     778            sage: x = var('x')
     779            sage: f = exp_integral_ci(x)
     780            sage: f.diff(x)
     781            cos(x)/x
     782
     783            sage: f = exp_integral_ci(x^2)
     784            sage: f.diff(x)
     785            2*cos(x^2)/x
     786
     787        """
     788        return cos(z)/z
     789
     790exp_integral_ci = Function_exp_integral_ci()
     791
     792
     793class Function_exp_integral_shi(BuiltinFunction):
     794    r"""
     795    The trigonometric integral `\operatorname{Shi}(z)` defined by
     796
     797    .. math::
     798
     799        \operatorname{Shi}(z) = \int_0^z \frac{\sinh(t)}{t}\; dt,
     800
     801    see [AS]_ 5.2.3.
     802
     803    EXAMPLES:
     804
     805    Numerical evaluation for real and complex arguments is handled using mpmath::
     806
     807        sage: exp_integral_shi(3.0)
     808        4.97344047585981
     809        sage: exp_integral_shi(1.0)
     810        1.05725087537573
     811        sage: exp_integral_shi(-1.0)
     812        -1.05725087537573
     813
     814    Compare ``exp_integral_shi(3.0)`` to the definition of the value using
     815    numerical integration::
     816
     817        sage: N(integrate((sinh(x))/x, x, 0, 3.0) - exp_integral_shi(3.0)) < 1e-14
     818        True
     819
     820    Arbitrary precision and complex arguments are handled::
     821
     822        sage: N(exp_integral_shi(3), digits=30)
     823        4.97344047585980679771041838252
     824        sage: exp_integral_shi(ComplexField(100)(3+I))
     825        3.9134623660329374406788354078 + 3.0427678212908839256360163759*I
     826
     827    The limit `\operatorname{Shi}(z)` as `z \to \infty` is `\infty`::
     828
     829        sage: N(exp_integral_shi(Infinity))
     830        +infinity
     831
     832    Symbolic derivatives and integrals are handled by Sage and Maxima::
     833
     834        sage: x = var('x')
     835        sage: f = exp_integral_shi(x)
     836        sage: f.diff(x)
     837        sinh(x)/x
     838
     839        sage: f.integrate(x)
     840        x*exp_integral_shi(x) - cosh(x)
     841
     842    ALGORITHM:
     843
     844    Numerical evaluation is handled using mpmath, but symbolics are handled
     845    by Sage and Maxima.
     846
     847    REFERENCES:
     848
     849    - http://en.wikipedia.org/wiki/Trigonometric_integral
     850    - mpmath documentation: `shi`_
     851
     852    .. _`shi`: http://mpmath.googlecode.com/svn/trunk/doc/build/functions/expintegrals.html#shi
     853
     854    """
     855    def __init__(self):
     856        """
     857        See the docstring for ``Function_exp_integral_shi``.
     858
     859        EXAMPLES::
     860
     861            sage: exp_integral_shi(1)
     862            exp_integral_shi(1)
     863
     864        """
     865        BuiltinFunction.__init__(self, "exp_integral_shi", nargs=1, latex_name=r'\operatorname{Shi}', conversions=dict(maxima='expintegral_shi'))
     866
     867    def _eval_(self, z):
     868        """
     869        EXAMPLES::
     870
     871            sage: z = var('z')
     872            sage: exp_integral_shi(z)
     873            exp_integral_shi(z)
     874            sage: exp_integral_shi(3.0)
     875            4.97344047585981
     876            sage: exp_integral_shi(0)
     877            0
     878
     879        """
     880        if not isinstance(z, Expression) and is_inexact(z):
     881            return self._evalf_(z, parent(z))
     882
     883        # special case: z = 0
     884        if isinstance(z, Expression):
     885            if z._is_numerically_zero():
     886                return 0
     887        else:
     888            if not z:
     889                return 0
     890
     891        return None # leaves the expression unevaluated
     892
     893    def _evalf_(self, z, parent=None):
     894        """
     895        EXAMPLES::
     896
     897            sage: N(exp_integral_shi(1e-10), digits=30)
     898            1.00000000000000003643219731550e-10
     899            sage: exp_integral_shi(ComplexField(100)(I))
     900            0.94608307036718301494135331382*I
     901
     902        """
     903        import mpmath
     904        return mpmath_utils_call(mpmath.shi, z, parent=parent)
     905
     906    def _derivative_(self, z, diff_param=None):
     907        """
     908        The derivative of `\operatorname{Shi}(z)` is `\sinh(z)/z`.
     909
     910        EXAMPLES::
     911
     912            sage: x = var('x')
     913            sage: f = exp_integral_shi(x)
     914            sage: f.diff(x)
     915            sinh(x)/x
     916
     917            sage: f = exp_integral_shi(ln(x))
     918            sage: f.diff(x)
     919            sinh(log(x))/(x*log(x))
     920
     921        """
     922        return sinh(z)/z
     923
     924exp_integral_shi = Function_exp_integral_shi()
     925
     926
     927class Function_exp_integral_chi(BuiltinFunction):
     928    r"""
     929    The trigonometric integral `\operatorname{Chi}(z)` defined by
     930
     931    .. math::
     932
     933        \operatorname{Chi}(z) = \gamma + \log(z) + \int_0^z \frac{\cosh(t)-1}{t}\; dt,
     934
     935    see [AS]_ 5.2.4.
     936
     937    EXAMPLES:
     938
     939    Numerical evaluation for real and complex arguments is handled using mpmath::
     940
     941        sage: exp_integral_chi(1.0)
     942        0.837866940980208
     943
     944    Here is an example from the mpmath documentation::
     945
     946        sage: f(x) = exp_integral_chi(x)
     947        sage: find_root(f, 0.1, 1.0)
     948        0.52382257138948263
     949
     950    Compare ``exp_integral_chi(3.0)`` to the definition of the value using
     951    numerical integration::
     952
     953        sage: N(euler_gamma + log(3.0) + integrate((cosh(x)-1)/x, x, 0, 3.0) -
     954        ...     exp_integral_chi(3.0)) < 1e-14
     955        True
     956
     957    Arbitrary precision and complex arguments are handled::
     958
     959        sage: N(exp_integral_chi(3), digits=30)
     960        4.96039209476560976029791763669
     961        sage: exp_integral_chi(ComplexField(100)(3+I))
     962        3.9096723099686417127843516794 + 3.0547519627014217273323873274*I
     963
     964    The limit of `\operatorname{Chi}(z)` as `z \to \infty` is `\infty`::
     965
     966        sage: N(exp_integral_chi(Infinity))
     967        +infinity
     968
     969    Symbolic derivatives and integrals are handled by Sage and Maxima::
     970
     971        sage: x = var('x')
     972        sage: f = exp_integral_chi(x)
     973        sage: f.diff(x)
     974        cosh(x)/x
     975
     976        sage: f.integrate(x)
     977        x*exp_integral_chi(x) - sinh(x)
     978
     979    ALGORITHM:
     980
     981    Numerical evaluation is handled using mpmath, but symbolics are handled
     982    by Sage and Maxima.
     983
     984    REFERENCES:
     985
     986    - http://en.wikipedia.org/wiki/Trigonometric_integral
     987    - mpmath documentation: `chi`_
     988
     989    .. _`chi`: http://mpmath.googlecode.com/svn/trunk/doc/build/functions/expintegrals.html#chi
     990
     991    """
     992    def __init__(self):
     993        """
     994        See the docstring for ``Function_exp_integral_chi``.
     995
     996        EXAMPLES::
     997
     998            sage: exp_integral_chi(1)
     999            exp_integral_chi(1)
     1000
     1001        """
     1002        BuiltinFunction.__init__(self, "exp_integral_chi", nargs=1, latex_name=r'\operatorname{Chi}', conversions=dict(maxima='expintegral_chi'))
     1003
     1004    def _eval_(self, z):
     1005        """
     1006        EXAMPLES::
     1007
     1008            sage: z = var('z')
     1009            sage: exp_integral_chi(z)
     1010            exp_integral_chi(z)
     1011            sage: exp_integral_chi(3.0)
     1012            4.96039209476561
     1013
     1014        """
     1015        if not isinstance(z, Expression) and is_inexact(z):
     1016            return self._evalf_(z, parent(z))
     1017
     1018        return None
     1019
     1020    def _evalf_(self, z, parent=None):
     1021        """
     1022        EXAMPLES::
     1023
     1024            sage: N(exp_integral_chi(1e-10), digits=30)
     1025            -22.4486352650389235918737540487
     1026            sage: exp_integral_chi(ComplexField(100)(I))
     1027            0.33740392290096813466264620389 + 1.5707963267948966192313216916*I
     1028
     1029        """
     1030        import mpmath
     1031        return mpmath_utils_call(mpmath.chi, z, parent=parent)
     1032
     1033    def _derivative_(self, z, diff_param=None):
     1034        """
     1035        The derivative of `\operatorname{Chi}(z)` is `\cosh(z)/z`.
     1036
     1037        EXAMPLES::
     1038
     1039            sage: x = var('x')
     1040            sage: f = exp_integral_chi(x)
     1041            sage: f.diff(x)
     1042            cosh(x)/x
     1043
     1044            sage: f = exp_integral_chi(ln(x))
     1045            sage: f.diff(x)
     1046            cosh(log(x))/(x*log(x))
     1047
     1048        """
     1049        return cosh(z)/z
     1050
     1051exp_integral_chi = Function_exp_integral_chi()
     1052
     1053
     1054#############################################
     1055## Code below here was moved from either:
     1056## - sage/functions/transcendental.py
     1057## - sage/functions/special.py
     1058## This occured as part of Trac #11143.
     1059#############################################
     1060
     1061# moved here from sage/functions/special.py
     1062def exp_int(t):
     1063    r"""
     1064    The exponential integral `\int_t^\infty e^{-x}/x \; dx` (`t`
     1065    belongs to `\mathbb{R}`).  This function is deprecated - please use
     1066    ``Ei`` or ``exponential_integral_1`` as needed instead.
     1067
     1068    EXAMPLES::
     1069
     1070        sage: exp_int(6)
     1071        doctest:...: DeprecationWarning: The method exp_int() is deprecated. Use -Ei(-x) or exponential_integral_1(x) as needed instead.
     1072        0.000360082452162659
     1073    """
     1074    from sage.misc.misc import deprecation
     1075    deprecation("The method exp_int() is deprecated. Use -Ei(-x) or exponential_integral_1(x) as needed instead.")
     1076    try:
     1077        return t.eint1()
     1078    except AttributeError:
     1079        from sage.libs.pari.all import pari
     1080        try:
     1081            return pari(t).eint1()
     1082        except:
     1083            raise NotImplementedError
     1084
     1085# moved here from sage/functions/transcendental.py
     1086#
     1087# This class has a name which is not specific enough
     1088# see Function_exp_integral_e above, for example, which
     1089# is the "generalized" exponential integral function. We
     1090# are leaving the name the same for backwards compatibility
     1091# purposes.
     1092class Function_exp_integral(BuiltinFunction):
     1093    r"""
     1094    The generalized complex exponential integral Ei(z) defined by
     1095
     1096    .. math::
     1097
     1098        \operatorname{Ei}(x) = \int_{-\infty}^x \frac{e^t}{t}\; dt
     1099
     1100    for x > 0 and for complex arguments by analytic continuation,
     1101    see [AS]_ 5.1.2.
     1102
     1103    EXAMPLES::
     1104
     1105        sage: Ei(10)
     1106        Ei(10)
     1107        sage: Ei(I)
     1108        Ei(I)
     1109        sage: Ei(3+I)
     1110        Ei(I + 3)
     1111        sage: Ei(1.3)
     1112        2.72139888023202
     1113
     1114    The branch cut for this function is along the negative real axis::
     1115
     1116        sage: Ei(-3 + 0.1*I)
     1117        -0.0129379427181693 + 3.13993830250942*I
     1118        sage: Ei(-3 - 0.1*I)
     1119        -0.0129379427181693 - 3.13993830250942*I
     1120
     1121    ALGORITHM: Uses mpmath.
     1122
     1123    """
     1124    def __init__(self):
     1125        """
     1126        Return the value of the complex exponential integral Ei(z) at a
     1127        complex number z.
     1128
     1129        EXAMPLES::
     1130
     1131            sage: Ei(10)
     1132            Ei(10)
     1133            sage: Ei(I)
     1134            Ei(I)
     1135            sage: Ei(3+I)
     1136            Ei(I + 3)
     1137            sage: Ei(1.3)
     1138            2.72139888023202
     1139
     1140        The branch cut for this function is along the negative real axis::
     1141
     1142            sage: Ei(-3 + 0.1*I)
     1143            -0.0129379427181693 + 3.13993830250942*I
     1144            sage: Ei(-3 - 0.1*I)
     1145            -0.0129379427181693 - 3.13993830250942*I
     1146
     1147        ALGORITHM: Uses mpmath.
     1148        """
     1149        BuiltinFunction.__init__(self, "Ei")
     1150
     1151    def _eval_(self, x ):
     1152        """
     1153        EXAMPLES::
     1154
     1155            sage: Ei(10)
     1156            Ei(10)
     1157            sage: Ei(I)
     1158            Ei(I)
     1159            sage: Ei(1.3)
     1160            2.72139888023202
     1161            sage: Ei(10r)
     1162            Ei(10)
     1163            sage: Ei(1.3r)
     1164            2.7213988802320235
     1165        """
     1166        if not isinstance(x, Expression) and is_inexact(x):
     1167            return self._evalf_(x, parent(x))
     1168        return None
     1169
     1170    def _evalf_(self, x, parent=None):
     1171        """
     1172        EXAMPLES::
     1173
     1174            sage: Ei(10).n()
     1175            2492.22897624188
     1176            sage: Ei(20).n()
     1177            2.56156526640566e7
     1178            sage: Ei(I).n()
     1179            0.337403922900968 + 2.51687939716208*I
     1180            sage: Ei(3+I).n()
     1181            7.82313467600158 + 6.09751978399231*I
     1182        """
     1183        import mpmath
     1184        return mpmath_utils_call(mpmath.ei, x, parent=parent)
     1185
     1186    def __call__(self, x, prec=None, coerce=True, hold=False ):
     1187        """
     1188        Note that the ``prec`` argument is deprecated. The precision for
     1189        the result is deduced from the precision of the input. Convert
     1190        the input to a higher precision explicitly if a result with higher
     1191        precision is desired.
     1192
     1193        EXAMPLES::
     1194
     1195            sage: t = Ei(RealField(100)(2.5)); t
     1196            7.0737658945786007119235519625
     1197            sage: t.prec()
     1198            100
     1199
     1200            sage: Ei(1.1, prec=300)
     1201            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.
     1202            2.16737827956340306615064476647912607220394065907142504328679588538509331805598360907980986
     1203        """
     1204        if prec is not None:
     1205            from sage.misc.misc import deprecation
     1206            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.")
     1207
     1208            import mpmath
     1209            return mpmath_utils_call(mpmath.ei, x, prec=prec)
     1210
     1211        return BuiltinFunction.__call__(self, x, coerce=coerce, hold=hold)
     1212
     1213    def _derivative_(self, x, diff_param=None):
     1214        """
     1215        EXAMPLES::
     1216
     1217            sage: Ei(x).diff(x)
     1218            e^x/x
     1219            sage: Ei(x).diff(x).subs(x=1)
     1220            e
     1221            sage: Ei(x^2).diff(x)
     1222            2*e^(x^2)/x
     1223            sage: f = function('f')
     1224            sage: Ei(f(x)).diff(x)
     1225            e^f(x)*D[0](f)(x)/f(x)
     1226        """
     1227        return exp(x)/x
     1228
     1229Ei = exp_integral_ei = Function_exp_integral()
     1230
     1231
     1232# moved here from sage/functions/transcendental.py
     1233def exponential_integral_1(x, n=0):
     1234    r"""
     1235    Returns the exponential integral `E_1(x)`. If the optional
     1236    argument `n` is given, computes list of the first
     1237    `n` values of the exponential integral
     1238    `E_1(x m)`.
     1239
     1240    The exponential integral `E_1(x)` is
     1241
     1242    .. math::
     1243
     1244                      E_1(x) = \int_{x}^{\infty} e^{-t}/t dt
     1245
     1246
     1247
     1248    INPUT:
     1249
     1250
     1251    -  ``x`` - a positive real number
     1252
     1253    -  ``n`` - (default: 0) a nonnegative integer; if
     1254       nonzero, then return a list of values E_1(x\*m) for m =
     1255       1,2,3,...,n. This is useful, e.g., when computing derivatives of
     1256       L-functions.
     1257
     1258
     1259    OUTPUT:
     1260
     1261
     1262    -  ``float`` - if n is 0 (the default) or
     1263
     1264    -  ``list`` - list of floats if n 0
     1265
     1266
     1267    EXAMPLES::
     1268
     1269        sage: exponential_integral_1(2)
     1270        0.048900510708061118
     1271        sage: w = exponential_integral_1(2,4); w
     1272        [0.048900510708061118, 0.0037793524098489067, 0.00036008245216265873, 3.7665622843924751e-05] # 32-bit
     1273        [0.048900510708061118, 0.0037793524098489063, 0.00036008245216265873, 3.7665622843924534e-05] # 64-bit
     1274
     1275    IMPLEMENTATION: We use the PARI C-library functions eint1 and
     1276    veceint1.
     1277
     1278    REFERENCE:
     1279
     1280    - See page 262, Prop 5.6.12, of Cohen's book "A Course in
     1281      Computational Algebraic Number Theory".
     1282
     1283    REMARKS: When called with the optional argument n, the PARI
     1284    C-library is fast for values of n up to some bound, then very very
     1285    slow. For example, if x=5, then the computation takes less than a
     1286    second for n=800000, and takes "forever" for n=900000.
     1287    """
     1288    if isinstance(x, Expression):
     1289        raise NotImplementedError("Use the symbolic exponential integral " +
     1290        "function: exp_integral_e1.")
     1291    from sage.libs.pari.all import pari
     1292    if n <= 0:
     1293        return float(pari(x).eint1())
     1294    else:
     1295        return [float(z) for z in pari(x).eint1(n)]
  • sage/functions/other.py

    diff --git a/sage/functions/other.py b/sage/functions/other.py
    a b  
    1919from sage.symbolic.constants import pi
    2020from sage.symbolic.function import is_inexact
    2121from sage.functions.log import exp
    22 from sage.functions.transcendental import Ei
     22from sage.functions.exp_integral import Ei
    2323from sage.libs.mpmath import utils as mpmath_utils
    2424
    2525one_half = ~SR(2)
  • sage/functions/special.py

    diff --git a/sage/functions/special.py b/sage/functions/special.py
    a b  
    17151715        except:
    17161716            raise NotImplementedError
    17171717
    1718 def exp_int(t):
    1719     r"""
    1720     The exponential integral `\int_t^\infty e^{-x}/x dx` (t
    1721     belongs to RR).  This function is deprecated - please use
    1722     ``Ei`` or ``exponential_integral_1`` as needed instead.
    1723 
    1724     EXAMPLES::
    1725        
    1726         sage: exp_int(6)
    1727         doctest:...: DeprecationWarning: The method exp_int() is deprecated. Use -Ei(-x) or exponential_integral_1(x) as needed instead.
    1728         0.000360082452162659
    1729     """
    1730     from sage.misc.misc import deprecation
    1731     deprecation("The method exp_int() is deprecated. Use -Ei(-x) or exponential_integral_1(x) as needed instead.")
    1732     try:
    1733         return t.eint1()
    1734     except AttributeError:
    1735         from sage.libs.pari.all import pari
    1736         try:
    1737             return pari(t).eint1()
    1738         except:
    1739             raise NotImplementedError
    1740 
    17411718def error_fcn(t):
    17421719    r"""
    17431720    The complementary error function
  • sage/functions/transcendental.py

    diff --git a/sage/functions/transcendental.py b/sage/functions/transcendental.py
    a b  
    1818#*****************************************************************************
    1919
    2020import sys
    21 from sage.libs.mpmath import utils as mpmath_utils
    2221import  sage.libs.pari.all
    2322from sage.libs.pari.all import pari
    2423import sage.rings.complex_field as complex_field
     
    3938CC = complex_field.ComplexField()
    4039I = CC.gen(0)
    4140
    42 def exponential_integral_1(x, n=0):
    43     r"""
    44     Returns the exponential integral `E_1(x)`. If the optional
    45     argument `n` is given, computes list of the first
    46     `n` values of the exponential integral
    47     `E_1(x m)`.
    48    
    49     The exponential integral `E_1(x)` is
    50    
    51     .. math::
    52    
    53                       E_1(x) = \int_{x}^{\infty} e^{-t}/t dt     
    54    
    55    
    56    
    57     INPUT:
    58    
    59    
    60     -  ``x`` - a positive real number
    61    
    62     -  ``n`` - (default: 0) a nonnegative integer; if
    63        nonzero, then return a list of values E_1(x\*m) for m =
    64        1,2,3,...,n. This is useful, e.g., when computing derivatives of
    65        L-functions.
    66    
    67    
    68     OUTPUT:
    69    
    70    
    71     -  ``float`` - if n is 0 (the default) or
    72    
    73     -  ``list`` - list of floats if n 0
    74    
    75    
    76     EXAMPLES::
    77    
    78         sage: exponential_integral_1(2)
    79         0.048900510708061118
    80         sage: w = exponential_integral_1(2,4); w
    81         [0.048900510708061118, 0.0037793524098489067, 0.00036008245216265873, 3.7665622843924751e-05] # 32-bit
    82         [0.048900510708061118, 0.0037793524098489063, 0.00036008245216265873, 3.7665622843924534e-05] # 64-bit
    83    
    84     IMPLEMENTATION: We use the PARI C-library functions eint1 and
    85     veceint1.
    86    
    87     REFERENCE:
    88 
    89     - See page 262, Prop 5.6.12, of Cohen's book "A Course in
    90       Computational Algebraic Number Theory".
    91    
    92     REMARKS: When called with the optional argument n, the PARI
    93     C-library is fast for values of n up to some bound, then very very
    94     slow. For example, if x=5, then the computation takes less than a
    95     second for n=800000, and takes "forever" for n=900000.
    96     """
    97     if n <= 0:
    98         return float(pari(x).eint1())
    99     else:
    100         return [float(z) for z in pari(x).eint1(n)]
    101 
    102 
    10341class Function_zeta(GinacFunction):
    10442    def __init__(self):
    10543        r"""
     
    242180    return (s/2 + 1).gamma()   *    (s-1)   * (R.pi()**(-s/2))  *  s.zeta()
    243181
    244182
    245 ##     # Use PARI on complex nubmer
    246 ##     prec = s.prec()
    247 ##     s = pari.new_with_bits_prec(s, prec)
    248 ##     pi = pari.pi()
    249 ##     w = (s/2 + 1).gamma() * (s-1) * pi **(-s/2) * s.zeta()
    250 ##     z = w._sage_()
    251 ##     if z.prec() < prec:
    252 ##         raise RuntimeError, "Error computing zeta_symmetric(%s) -- precision loss."%s
    253 ##     return z
    254 
    255 
    256 #def pi_approx(prec=53):
    257 #    """
    258 #    Return pi computed to prec bits of precision.
    259 #    """
    260 #   return real_field.RealField(prec).pi()
    261 
    262 
    263 class Function_exp_integral(BuiltinFunction):
    264     def __init__(self):
    265         """
    266         Return the value of the complex exponential integral Ei(z) at a
    267         complex number z.
    268        
    269         EXAMPLES::
    270 
    271             sage: Ei(10)
    272             Ei(10)
    273             sage: Ei(I)
    274             Ei(I)
    275             sage: Ei(3+I)
    276             Ei(I + 3)
    277             sage: Ei(1.3)
    278             2.72139888023202
    279            
    280         The branch cut for this function is along the negative real axis::
    281    
    282             sage: Ei(-3 + 0.1*I)
    283             -0.0129379427181693 + 3.13993830250942*I
    284             sage: Ei(-3 - 0.1*I)
    285             -0.0129379427181693 - 3.13993830250942*I
    286    
    287         ALGORITHM: Uses mpmath.
    288         """
    289         BuiltinFunction.__init__(self, "Ei")
    290 
    291     def _eval_(self, x ):
    292         """
    293         EXAMPLES::
    294 
    295             sage: Ei(10)
    296             Ei(10)
    297             sage: Ei(I)
    298             Ei(I)
    299             sage: Ei(1.3)
    300             2.72139888023202
    301             sage: Ei(10r)
    302             Ei(10)
    303             sage: Ei(1.3r)
    304             2.72139888023202
    305         """
    306         if not isinstance(x, Expression) and is_inexact(x):
    307             return self._evalf_(x, parent(x))
    308         return None
    309            
    310     def _evalf_(self, x, parent=None):
    311         """
    312         EXAMPLES::
    313 
    314             sage: Ei(10).n()
    315             2492.22897624188
    316             sage: Ei(20).n()
    317             2.56156526640566e7
    318             sage: Ei(I).n()
    319             0.337403922900968 + 2.51687939716208*I
    320             sage: Ei(3+I).n()
    321             7.82313467600158 + 6.09751978399231*I
    322         """
    323         import mpmath
    324         if isinstance(parent, Parent) and hasattr(parent, 'prec'):
    325             prec = parent.prec()
    326         else:
    327             prec = 53
    328         return mpmath_utils.call(mpmath.ei, x, prec=prec)
    329 
    330     def __call__(self, x, prec=None, coerce=True, hold=False ):
    331         """
    332         Note that the ``prec`` argument is deprecated. The precision for
    333         the result is deduced from the precision of the input. Convert
    334         the input to a higher precision explicitly if a result with higher
    335         precision is desired.
    336 
    337         EXAMPLES::
    338 
    339             sage: t = Ei(RealField(100)(2.5)); t
    340             7.0737658945786007119235519625
    341             sage: t.prec()
    342             100
    343 
    344             sage: Ei(1.1, prec=300)
    345             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.
    346             2.16737827956340306615064476647912607220394065907142504328679588538509331805598360907980986
    347         """
    348         if prec is not None:
    349             from sage.misc.misc import deprecation
    350             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.")
    351            
    352             import mpmath
    353             return mpmath_utils.call(mpmath.ei, x, prec=prec)
    354 
    355         return BuiltinFunction.__call__(self, x, coerce=coerce, hold=hold)
    356 
    357     def _derivative_(self, x, diff_param=None):
    358         """
    359         EXAMPLES::
    360        
    361             sage: Ei(x).diff(x)
    362             e^x/x
    363             sage: Ei(x).diff(x).subs(x=1)
    364             e
    365             sage: Ei(x^2).diff(x)
    366             2*e^(x^2)/x
    367             sage: f = function('f')
    368             sage: Ei(f(x)).diff(x)
    369             e^f(x)*D[0](f)(x)/f(x)
    370         """
    371         return exp(x)/x
    372 
    373 Ei = Function_exp_integral()
    374 
    375 
    376183def Li(x, eps_rel=None, err_bound=False):
    377184    r"""
    378185    Return value of the function Li(x) as a real double field element.
  • sage/interfaces/maxima_lib.py

    diff --git a/sage/interfaces/maxima_lib.py b/sage/interfaces/maxima_lib.py
    a b  
    12271227    sage.functions.log.polylog : lambda N,X : [[mqapply],[[max_li, max_array],N],X],
    12281228    sage.functions.other.psi1 : lambda X : [[mqapply],[[max_psi, max_array],0],X],
    12291229    sage.functions.other.psi2 : lambda N,X : [[mqapply],[[max_psi, max_array],N],X],
    1230     sage.functions.other.Ei : lambda X : [[max_gamma_incomplete], 0, X]
     1230    sage.functions.exp_integral.Ei : lambda X : [[max_gamma_incomplete], 0, X]
    12311231}
    12321232
    12331233
  • sage/misc/sagedoc.py

    diff --git a/sage/misc/sagedoc.py b/sage/misc/sagedoc.py
    a b  
    869869    ``search_src(string, interact=False).splitlines()`` gives the
    870870    number of matches. ::
    871871
    872         sage: len(search_src('log', 'derivative', interact=False).splitlines()) < 8
     872        sage: len(search_src('log', 'derivative', interact=False).splitlines()) < 9
    873873        True
    874874        sage: len(search_src('log', 'derivative', interact=False, multiline=True).splitlines()) > 30
    875875        True
     
    891891        misc/sagedoc.py:... s = search_src('Matrix', path_re='matrix', interact=False); s.find('x') > 0
    892892        misc/sagedoc.py:... s = search_src('MatRiX', path_re='matrix', interact=False); s.find('x') > 0
    893893        misc/sagedoc.py:... s = search_src('MatRiX', path_re='matrix', interact=False, ignore_case=True); s.find('x') > 0
    894         misc/sagedoc.py:... len(search_src('log', 'derivative', interact=False).splitlines()) < 8
     894        misc/sagedoc.py:... len(search_src('log', 'derivative', interact=False).splitlines()) < 9
    895895        misc/sagedoc.py:... len(search_src('log', 'derivative', interact=False, multiline=True).splitlines()) > 30
    896896        misc/sagedoc.py:... print search_src('^ *sage[:] .*search_src\(', interact=False) # long time
    897897        misc/sagedoc.py:... len(search_src("matrix", interact=False).splitlines()) > 9000 # long time
  • sage/schemes/elliptic_curves/lseries_ell.py

    diff --git a/sage/schemes/elliptic_curves/lseries_ell.py b/sage/schemes/elliptic_curves/lseries_ell.py
    a b  
    99    RationalField,
    1010    ComplexField)
    1111from math import sqrt, exp, ceil
    12 import sage.functions.transcendental as transcendental
     12import sage.functions.exp_integral as exp_integral
    1313R = RealField()
    1414Q = RationalField()
    1515C = ComplexField()
     
    470470        an = self.__E.anlist(k)           # list of C ints
    471471        # Compute z = e^(-2pi/sqrt(N))
    472472        pi = 3.14159265358979323846
    473         v = transcendental.exponential_integral_1(2*pi/sqrtN, k)
     473        v = exp_integral.exponential_integral_1(2*pi/sqrtN, k)
    474474        L = 2*float(sum([ (v[n-1] * an[n])/n for n in xrange(1,k+1)]))
    475475        error = 2*exp(-2*pi*(k+1)/sqrtN)/(1-exp(-2*pi/sqrtN))
    476476        return R(L), R(error)
  • sage/symbolic/random_tests.py

    diff --git a/sage/symbolic/random_tests.py b/sage/symbolic/random_tests.py
    a b  
    1414
    1515        sage: from sage.symbolic.random_tests import _mk_full_functions
    1616        sage: [f for (one,f,arity) in _mk_full_functions()]
    17         [Ei, abs, arccos, arccosh, arccot, arccoth, arccsc, arccsch,
    18         arcsec, arcsech, arcsin, arcsinh, arctan, arctan2, arctanh,
    19         binomial, ceil, conjugate, cos, cosh, cot, coth, csc, csch,
    20         dickman_rho, dilog, dirac_delta, elliptic_e, elliptic_ec,
    21         elliptic_eu, elliptic_f, elliptic_kc, elliptic_pi, erf, exp,
    22         factorial, floor, heaviside, imag_part, integrate,
    23         kronecker_delta, log, polylog, real_part, sec, sech, sgn, sin,
    24         sinh, tan, tanh, unit_step, zeta, zetaderiv]
     17        [Ei, abs, arccos, arccosh, arccot, arccoth, arccsc, arccsch, arcsec,
     18        arcsech, arcsin, arcsinh, arctan, arctan2, arctanh, binomial, ceil,
     19        conjugate, cos, cosh, cot, coth, csc, csch, dickman_rho, dilog,
     20        dirac_delta, elliptic_e, elliptic_ec, elliptic_eu, elliptic_f,
     21        elliptic_kc, elliptic_pi, erf, exp, exp_integral_chi, exp_integral_ci,
     22        exp_integral_e, exp_integral_e1, exp_integral_li, exp_integral_shi,
     23        exp_integral_si, factorial, floor, heaviside, imag_part, integrate,
     24        kronecker_delta, log, polylog, real_part, sec, sech, sgn, sin, sinh,
     25        tan, tanh, unit_step, zeta, zetaderiv]
    2526
    2627    Note that this doctest will fail whenever a Pynac function is added or
    2728    removed.  In that case, it is very likely that the doctests for
     
    234235        sage: from sage.symbolic.random_tests import *
    235236        sage: set_random_seed(2)
    236237        sage: random_expr(50, nvars=3, coeff_generator=CDF.random_element)
    237         (euler_gamma - v3^(-e) + (v2 - factorial(-e/v2))^(((2.85879036573 - 1.18163393202*I)*v2 + (2.85879036573 - 1.18163393202*I)*v3)*pi - 0.247786879678 + 0.931826724898*I)*arccsc((0.891138386848 - 0.0936820840629*I)/v1) - (0.553423153995 - 0.5481180572*I)*v3 + 0.149683576515 - 0.155746451854*I)*v1 + arccsch(pi + e)*elliptic_f(khinchin*v2, 1.4656989704 + 0.863754357069*I)
     238        -v1*e^((0.0666829501658 + 0.206976992303*I)/(v3 + e))/v3 + exp_integral_si(arccot(-(v3^(-0.48519994364 - 0.485764091302*I) - polylog(-(0.700685987017 + 0.989350434299*I)/(pi*v1), -(v1 + v3 - 0.0237664220295 - 0.234827623598*I)*v1*exp_integral_shi(-elliptic_f(v1, 0.0417281846726 + 0.563674475814*I)/(pi*v3))))*v1))
    238239        sage: random_expr(5, verbose=True)
    239         About to apply dirac_delta to [1]
    240         About to apply arccsch to [0]
    241         About to apply <built-in function add> to [0, arccsch(0)]
    242         arccsch(0)
     240        About to apply <built-in function neg> to [v1]
     241        About to apply <built-in function pow> to [v1, -v1]
     242        About to apply sin to [v1^(-v1)]
     243        sin(v1^(-v1))
     244
    243245    """
    244246    vars = [(1.0, sage.calculus.calculus.var('v%d' % (n+1))) for n in range(nvars)]
    245247    if ncoeffs is None: