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.

Reply via email to