On Dec 22, 2008, at 8:28 AM, M. Yurko wrote:

> When I timed these functions over 1 through 700 at 53 bits of
> precision, the python one took 5.46 sec., the double precision cython
> one took only .02 sec., and the arbitrary precision one took 6.77 sec.
> After looking at the .c file that cython generated, it seems to be
> doing a lot of conversions as simply initializing sum_current took
> almost 20 long lines of code.

I'm not sure why the Python function is faster, this is something to  
look at. However, I notice that you're not really using the fact that  
these are real numbers (i.e. not calling any cdef'd methods/using any  
cdef'd values, etc.) so it's doing a bunch of extra typechecking on  
each assignment. However, even the pure Python version is slightly  
slower when compiled (not sure why, shouldn't be the case, but I've  
made http://trac.cython.org/cython_trac/ticket/174 for later  
investigation).

To really take advantage of cython, one wants to call mpfr directly.  
E.g.

%cython

from sage.all import RealNumber as makeRealNumber, euler_gamma, ln,  
Integer
from sage.rings.real_mpfr cimport RealNumber
from sage.libs.mpfr cimport *

def cython_arbitrary_mpfr(xx,bits):
     cdef int i = 1
     cdef RealNumber x = makeRealNumber(xx,min_prec=bits)
     cdef RealNumber sum_current = x + 0 # need a copy
     cdef RealNumber sum_last = makeRealNumber(0)
     cdef RealNumber term = x + 0 # need a copy
     cdef RealNumber tmp = makeRealNumber(0, min_prec=bits)
     cdef add_term = (ln(x)+euler_gamma).n(bits)
     while mpfr_cmp(sum_current.value, sum_last.value) != 0:
         i+=1
         mpfr_mul(term.value, term.value, x.value, GMP_RNDN)
         mpfr_div_ui(term.value, term.value, i, GMP_RNDN)
         mpfr_set(sum_last.value, sum_current.value, GMP_RNDN)
         mpfr_div_ui(tmp.value, term.value, i, GMP_RNDN)
         mpfr_add(sum_current.value, sum_current.value, tmp.value,  
GMP_RNDN)
     return sum_current + add_term

which is 12.5x faster than the pure Python version, and the advantage  
will grow as the required precision goes up (the part outside the  
loop is stilly pretty slow). I transcribed your algorithm directly  
for a fair comparison, but I notice you're dividing term by i twice  
(once at the bottom of the loop, once at the top) which could cut  
your time by another 35%. Note here I'm using mpfr calls directly,  
but creating RealNumbers to store the results so I don't have to  
worry about memory management. The loop is pure C.

All that being said, I agree it's worth looking into how we're using  
pari, and if it's been fixed in the meantime. I'm not confident that  
the algorithm above will always give the result to the desired  
precision.

- Robert


--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to 
sage-support-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---

Reply via email to