#11143: define symbolic functions for exponential integrals
-----------------------------+----------------------------------------------
   Reporter:  kcrisman       |          Owner:  burcin                       
       Type:  defect         |         Status:  new                          
   Priority:  major          |      Milestone:  sage-4.7.1                   
  Component:  symbolics      |       Keywords:  ei Ei special function maxima
Work_issues:                 |       Upstream:  N/A                          
   Reviewer:  Burcin Erocal  |         Author:  Benjamin Jones               
     Merged:                 |   Dependencies:                               
-----------------------------+----------------------------------------------
Changes (by benjaminfjones):

 * cc: benjaminfjones (removed)


Comment:

 The tests similar to `if z == 0` in `_eval_` do make a big difference. I
 guess this is well known, but I didn't realize how big the speed
 difference is.

 I made a little table below of some timings. In the first table , `_eval_`
 includes tests `if z == 0 and n > 1` and `if n == 0`. In the second table,
 there are no such if statements (so the special cases are not
 implemented). In the third table, the special cases are implementes as in
 `sage/functions/generalized.py` where an approximation of `z` (or `n`) is
 produced and checked instead of the symbol.

 {{{
 #!rst
 with ``if z == 0``

 =============================================   ========
   Test
 Time
 =============================================   ========
 sage: timeit("f = exp_integral_e(n,z)")                  1.44 ms
 sage: timeit("f = exp_integral_e(n,0)")                  929 µs
 sage: timeit("f = exp_integral_e(0,z)")                  1.41 ms
 sage: timeit("f = exp_integral_e(1.0,1.0)")              158 µs
 =============================================   ========

 without ``if z == 0``

 =============================================   ======
   Test
 Time
 =============================================   ======
 sage: timeit("f = exp_integral_e(n,z)")                 541 µs
 sage: timeit("f = exp_integral_e(n,0)")                 300 µs
 sage: timeit("f = exp_integral_e(0,z)")                 299 µs
 sage: timeit("f = exp_integral_e(1.0,1.0)")             161 µs
 =============================================   ======

 with:

 .. code-block:: python

         try:
             approx_z = ComplexIntervalField()(z)
             # if z is zero and n > 1
             if bool(approx_z.imag() == 0) and bool(approx_z.real() == 0):
                 if n > 1:
                     return 1/(n-1)
         except: # z is symbolic
             pass
         # if n is zero
         try:
             approx_n = ComplexIntervalField()(n)
             if bool(approx_n.imag() == 0) and bool(approx_n.real() == 0):
                 return exp(-z)/z
         except: # n is symbolic
             pass

 =============================================   ======
   Test
 Time
 =============================================   ======
 sage: timeit("f = exp_integral_e(n,z)")                 570 µs
 sage: timeit("f = exp_integral_e(n,0)")                 576 µs
 sage: timeit("f = exp_integral_e(0,z)")                 1.05 ms
 sage: timeit("f = exp_integral_e(1.0,1.0)")             160 µs
 =============================================   ======
 }}}

 Timings in tables 2 and 3 are close except in the case where ``exp(-z)/z``
 is
 returned, whereas table 1 is anywhere from a factor of 3 to 5 slower than
 in table 2 when a symbolic argument is passed. Anyway, I thought I'd
 include the above for other beginners such as myself.

 --------------

 Another thing I discovered is that these two special cases that I was
 implementing are known to Maxima:

 {{{
 sage: f = exp_integral_e(0,x)
 sage: f
 exp_integral_e(0,x)
 sage: f.simplify()
 e^(-x)/x

 sage: nn = var('nn')
 sage: assume(nn > 1)
 sage: f = exp_integral_e(nn, 0)
 sage: f
 exp_integral_e(nn, 0)
 sage: f.simplify()
 1/(nn - 1)
 }}}

 So I think in the interest of speedy evaluation it's best to leave the
 special
 cases out, but point out in the documentation that Maxima knows about
 them.

 I've uploaded a new patch. I'll start implementing the other exponential
 integrals using this as a template.

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/11143#comment:15>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sage-trac?hl=en.

Reply via email to