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 -~----------~----~----~----~------~----~------~--~---