Comment #17 on issue 2607 by [email protected]: as_numer_denom() is too slow
http://code.google.com/p/sympy/issues/detail?id=2607
I see two simple limiting cases: all denoms the same and all denoms
having the same base raised to different powers. Your code 3 handles
the latter well and only one test fails. Sifting allows the former to
work well. The other limiting case is where all denoms are different
and your code 3 works fine with this, too. The failing test is for
solving `(exp(x) + exp(-x) - y)` for `x` and succeeds if the numerator
is expanded so I don't think this is a big problem.
In all your methods I compute numer and denom as
numers = {}
for n, d in [f.as_numer_denom() for f in self.args]:
numers.setdefault(d, []).append(n)
denoms = numers.keys()
numers = [Add(*numers[d]) for d in denoms]
Here are the results:
>>> from sympy.abc import *
>>> from sympy import *
>>> from timeit import timeit as T
All denoms the same
>>> T('Add(*(x**i for i in xrange(1000))).as_numer_denom0()',
'from sympy.abc import x\nfrom sympy import Add',number=1)
3.174272361316466
>>> T('Add(*(x**i for i in xrange(1000))).as_numer_denom1()',
'from sympy.abc import x\nfrom sympy import Add',number=1)
0.053110497724750516
>>> T('Add(*(x**i for i in xrange(1000))).as_numer_denom2()',
'from sympy.abc import x\nfrom sympy import Add',number=1)
0.07342214219945475
>>> T('Add(*(x**i for i in xrange(1000))).as_numer_denom3()',
'from sympy.abc import x\nfrom sympy import Add',number=1)
0.06052171791017358
All denoms with the same base
>>> T('Add(*(1/x**i for i in
xrange(1000))).as_numer_denom0()', 'from sympy.abc import x\nfrom
sympy import Add',number=1)
19.530945022855022
>>> T('Add(*(1/x**i for i in
xrange(1000))).as_numer_denom1()', 'from sympy.abc import x\nfrom
sympy import Add',number=1)
KeyboardInterrupt -- LONG time
>>> T('Add(*(1/x**i for i in
xrange(1000))).as_numer_denom2()', 'from sympy.abc import x\nfrom
sympy import Add',number=1)
20.545627503132437
>>> T('Add(*(1/x**i for i in
xrange(1000))).as_numer_denom3()', 'from sympy.abc import x\nfrom
sympy import Add',number=1)
4.866053063844362
All denoms different
Now using 100 instead of 1000
>>> T('Add(*(1/Dummy() for i in
xrange(100))).as_numer_denom0()', 'from sympy.abc import x\nfrom sympy
import Add, Dummy',number=1)
1.1850728715299965
>>> T('Add(*(1/Dummy() for i in
xrange(100))).as_numer_denom1()', 'from sympy.abc import x\nfrom sympy
import Add, Dummy',number=1)
34.04670873330474
>>> T('Add(*(1/Dummy() for i in
xrange(100))).as_numer_denom2()', 'from sympy.abc import x\nfrom sympy
import Add, Dummy',number=1)
1.1976072463441483
>>> T('Add(*(1/Dummy() for i in
xrange(100))).as_numer_denom3()', 'from sympy.abc import x\nfrom sympy
import Add, Dummy',number=1)
1.6892404011984468
So I would go with method 3 with the sifting modification as
previously discussed and coded above.
/c
--
You received this message because you are subscribed to the Google Groups
"sympy-issues" 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/sympy-issues?hl=en.