#8321: numerical integration with arbitrary precision
-------------------------+--------------------------------------------------
   Reporter:  burcin     |          Owner:  burcin              
       Type:  defect     |         Status:  needs_work          
   Priority:  major      |      Milestone:  sage-4.7.2          
  Component:  symbolics  |       Keywords:  numerics,integration
Work_issues:             |       Upstream:  N/A                 
   Reviewer:             |         Author:  Stefan Reiterer     
     Merged:             |   Dependencies:                      
-------------------------+--------------------------------------------------

Comment(by benjaminfjones):

 I wrote a small function to compare errors and timings of the GSL
 implementation (of `numerical_integral`) and the mpmath implementation
 provided by the patch. Here is the testing code:

 {{{
 #!python
 def num_int_test(f, a, b):
     """ Input: `f` should be a function of a single variable, [a, b] is a
 domain of integration """
     LJ = 25 # left justification
     from sage.symbolic.integration.integral import definite_integral
     exact_I = definite_integral(f, f.variables()[0], a, b)
     print "Exact ".ljust(LJ)     + " = %s" % exact_I
     print "Exact .n()".ljust(LJ) + " = %s" % exact_I.n()
     print "GSL".ljust(LJ)        + " = %s" % numerical_integral(f, a,
 b)[0]
     print "mpmath".ljust(LJ)     + " = %s" % definite_integral(f,
 f.variables()[0], a, b, hold=True).n()

     num_I = definite_integral(f, f.variables()[0], a, b, hold=True)
     for p in [53, 64, 100, 200, 500, 1000]:
         s = "mpmath (prec=%d)" % p
         print s.ljust(LJ) + " = %s" % num_I.n(p)

     print "Timings at prec=53:"
     print "    GSL: ",
     timeit('numerical_integral(%s, %s, %s)' % (f, a, b))
     print "    mpmath: ",
     timeit('definite_integral(%s, %s, %s, %s, hold=True).n()' % (f,
 f.variables()[0], a, b))
 }}}

 Now I took 3 examples from pg. 132 of the PDF suggested above at
 http://cannelle.lateralis.org/sagebook-1.0.pdf and tested them using
 `num_int_test`:

 {{{
 # applied patch http://trac.sagemath.org/sage_trac/raw-
 attachment/ticket/8321/trac_8321_rebase.patch
 sage: x = var('x')
 sage: from sage.symbolic.integration.integral import definite_integral

 # f = e^(-x^2)*log(x) on [17, 42]
 sage: num_int_test(e^(-x^2)*log(x), 17, 42)
 Exact                     = integrate(e^(-x^2)*log(x), x, 17, 42)
 Exact .n()                = 2.59225286296247e-127
 GSL                       = 2.5657285007e-127
 mpmath                    = 2.59225286296247e-127
 mpmath (prec=53)          = 2.59225286296247e-127
 mpmath (prec=64)          = 2.59225286296226841e-127
 mpmath (prec=100)         = 2.5922528629622683570941971829e-127
 mpmath (prec=200)         =
 2.5922528629622683570941971813123497913329093314031958452707e-127
 mpmath (prec=500)         =
 
2.56572850056105148291735639613047859001477095540203266250504462960653767523831161390072264481216550025343198689835357618681873598023026225266716067780e-127
 mpmath (prec=1000)        =
 
2.56572850056105148291735639613047859001477095540203266250504462960653767360416188079136395575326953119218247602307727367985551096000368640359367812179070686479198046287233104280204937504901221620134046153583613193738177820412122516350777255525035947116513676784199592200655526485894447669230515221776e-127
 Timings at prec=53:
     GSL:  625 loops, best of 3: 971 µs per loop
     mpmath:  25 loops, best of 3: 26.9 ms per loop

 # f = sqrt(1-x^2) on [0, 1]
 sage: num_int_test(sqrt(1-x^2), 0, 1)
 Exact                     = 1/4*pi
 Exact .n()                = 0.785398163397448
 GSL                       = 0.785398167726
 mpmath                    = 0.785398163397448
 mpmath (prec=53)          = 0.785398163397448
 mpmath (prec=64)          = 0.785398163397448310
 mpmath (prec=100)         = 0.78539816339744830961566084582
 mpmath (prec=200)         =
 0.78539816339744830961566084581987572104929234984377645524374
 mpmath (prec=500)         =
 
0.785398163397448309615660845819875721049292349843776455243736148076954101571552249657008706335529266995537021628320576661773461152387645557931339852032
 mpmath (prec=1000)        =
 
0.785398163397448309615660845819875721049292349843776455243736148076954101571552249657008706335529266995537021628320576661773461152387645557931339852032120279362571025675484630276389911155737238732595491107202743916483361532118912058446695791317800477286412141730865087152613581662053348401815062285318
 Timings at prec=53:
     GSL:  625 loops, best of 3: 652 µs per loop
     mpmath:  25 loops, best of 3: 12 ms per loop

 # f = sin(sin(x)) on [0, 1]
 sage: num_int_test(sin(sin(x)), 0, 1)
 Exact                     = integrate(sin(sin(x)), x, 0, 1)
 Exact .n()                = 0.430606103120691
 GSL                       = 0.430606103121
 mpmath                    = 0.430606103120691
 mpmath (prec=53)          = 0.430606103120691
 mpmath (prec=64)          = 0.430606103120690605
 mpmath (prec=100)         = 0.43060610312069060491237735525
 mpmath (prec=200)         =
 0.43060610312069060491237735524846578643360804182199746950463
 mpmath (prec=500)         =
 
0.430606103120690604912377355248465786433608041821997469504633350750892193636074792502000332212863495547968512886769444385260392350928954849458834511854
 mpmath (prec=1000)        =
 
0.430606103120690604912377355248465786433608041821997469504633350750892193636074792502000332212863495547968512886769444385260392350928954849458834511854394326788473583253436780737313870079328121429092122005425057044706514198162061316772646582265252772251628205725432156943890956907988745419355505731945
 Timings at prec=53:
     GSL:  625 loops, best of 3: 134 µs per loop
     mpmath:  25 loops, best of 3: 11.2 ms per loop
 }}}

 In the second example, GSL's answer compared to the numerically evaluated
 exact symbolic answer is significantly off. The mpmath answer at default
 precision matches the  numerically evaluated exact symbolic answer
 perfectly.

 As for the timings, as you can see GSL is *much* faster than the patch
 code using mpmath. I tried using `fast_callable` in the case where the
 domain precision is the same as RDF and that gives a big speedup, though
 still not as fast as GSL:

 {{{
 #!python
     def _evalf( ... ):
     ...

         try:
             precision = parent.prec()
             mpmath.mp.prec = precision
             if precision == RDF.precision():
                 mp_f = fast_callable(f, vars=[x], domain=RDF)
             else:
                 mp_f = lambda z: f(x = mpmath.mpmath_to_sage(z,
 precision))
         except AttributeError:
             mp_f = fast_callable(f, vars=[x], domain=RDF)

         return mpmath.call(mpmath.quad, mp_f, [a,b])
 }}}

 New timings using `fast_callable`:

 {{{
 # Testing: added fast_callable to _evalf_
 # results: definite_integral( ... ) is around 5x faster when called at RDF
 precision

 sage: timeit('numerical_integral(e^(-x^2)*log(x), 17, 42)') # base case
 using GSL at float precision
 625 loops, best of 3: 959 µs per loop
 sage: timeit('definite_integral(e^(-x^2)*log(x), x, 17, 42,
 hold=True).n()') # using fast_callable
 125 loops, best of 3: 5.41 ms per loop
 sage: timeit('definite_integral(e^(-x^2)*log(x), x, 17, 42,
 hold=True).n(53)') # using fast_callable
 125 loops, best of 3: 5.41 ms per loop
 sage: timeit('definite_integral(e^(-x^2)*log(x), x, 17, 42,
 hold=True).n(54)') # *not* using fast_callable
 25 loops, best of 3: 28.1 ms per loop
 sage: timeit('definite_integral(e^(-x^2)*log(x), x, 17, 42,
 hold=True).n(64)') # *not* using fast_callable
 25 loops, best of 3: 26.3 ms per loop
 sage: timeit('definite_integral(e^(-x^2)*log(x), x, 17, 42,
 hold=True).n(100)') # *not* using fast_callable
 25 loops, best of 3: 32.2 ms per loop
 }}}

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/8321#comment:31>
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