#4533: [with patch; needs work] divisors function slow for integers
----------------------+-----------------------------------------------------
 Reporter:  robertwb  |        Owner:  tbd       
     Type:  defect    |       Status:  new       
 Priority:  major     |    Milestone:  sage-3.2.1
Component:  algebra   |   Resolution:            
 Keywords:            |  
----------------------+-----------------------------------------------------
Changes (by was):

  * summary:  [with patch; needs review] divisors function slow for
              integers => [with patch; needs work] divisors
              function slow for integers

Comment:

 1. The new code isn't much faster, but it is certainly better.  Here are
 some before and after speed comparisons (core2 2.6Ghz 32-bit osx)

 Before:
 {{{
 sage: n = odd_part(factorial(31))
 sage: time _ = divisors(n)
 CPU times: user 1.66 s, sys: 0.03 s, total: 1.70 s
 Wall time: 1.73 s
 sage: n = 928304029834092384082304982093480293849028349823948
 sage: time _ = divisors(n)
 CPU times: user 0.30 s, sys: 0.06 s, total: 0.35 s
 Wall time: 0.46 s
 sage: n = 9283040298340
 sage: timeit('divisors(n)')
 125 loops, best of 3: 1.75 ms per loop
 }}}


 After:
 {{{
 sage: n = odd_part(factorial(31))
 sage: time _ = divisors(n)
 CPU times: user 0.90 s, sys: 0.06 s, total: 0.96 s
 Wall time: 0.98 s
 sage: time a = gp(n).divisors()
 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
 Wall time: 0.21 s
 sage: n = 928304029834092384082304982093480293849028349823948
 sage: time _ = divisors(n)
 CPU times: user 0.31 s, sys: 0.06 s, total: 0.37 s
 Wall time: 0.40 s
 sage: n = 9283040298340
 sage: timeit('divisors(n)')
 625 loops, best of 3: 341 µs per loop
 }}}

 2. It no longer works on int's, which is a serious problem (this used to
 work fine):

 {{{
 sage: divisors(int(5))
 Traceback (most recent call last):
 ...
 AttributeError: 'int' object has no attribute 'parent'
 }}}

 There should be a doctest about that.

 For a positive review fix the code to work on int/long as input, and add a
 doctest about that.   Regarding speeding it up to be on par with pari,
 that should be another ticket that *must* be opened before closing this
 one.  Ideas regarding speed:

    * you can easily precompute the length of the output list as
 {{{
 prod(e+1 for _,e in f)
 }}}
    * If the input is an int < long long (or long), could do all arithmetic
 with
 machine says data types, since you know a priori the biggest number that
 will appear.   This should be special cased.
    * Interestingly, I changed two lines of the function so it uses Python
 int's instead of Sage MPFR ints everywhere and the function speeds up
 dramatically so it is almost as fast as pari:
 {{{
     one = int(1)
     all = [one]
     for p, e in f:
         p = int(p)

 ...

 sage: time d = divisors(n)
 CPU times: user 0.23 s, sys: 0.02 s, total: 0.24 s
 Wall time: 0.25 s
 sage: time w = [ZZ(a) for a in d]
 CPU times: user 0.24 s, sys: 0.01 s, total: 0.25 s
 Wall time: 0.26 s
 sage: time w = gp(n).divisors()
 CPU times: user 0.00 s, sys: 0.01 s, total: 0.01 s
 Wall time: 0.18 s
 }}}

 Interestingly, as you can see above, doing everything with python ints,
 then converting all the python ints back to sage ints, results in
 something that is *twice* as fast as your code on the same input.


 3. Other remarks:

  * pari(n).divisors() gives an AttributeError, so I guess we never wrapped
 that.

  * Why is odd_part(factorial(31)) a RATIONAL?  This seems really weird.
 {{{
 sage: n = odd_part(factorial(31))
 sage: type(n)
 <type 'sage.rings.rational.Rational'>
 sage: type(factorial(31))
 <type 'sage.rings.integer.Integer'>
 }}}

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/4533#comment:6>
Sage <http://sagemath.org/>
Sage - Open Source Mathematical Software: Building the Car Instead of 
Reinventing the Wheel
--~--~---------~--~----~------------~-------~--~----~
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