Comment #29 on issue 2607 by [email protected]: as_numer_denom() is too slow
http://code.google.com/p/sympy/issues/detail?id=2607
I'm not sure what I'm missing here, but:
In [1]: numers, denoms = zip(*((Symbol('n%d'%i),Symbol('d%d'%i)) for i in
xrange(50)))
In [2]: a = Add(*(n/d for n, d in zip(numers, denoms)))
In [3]: %time u = a.as_numer_denom4()
CPU times: user 0.14 s, sys: 0.00 s, total: 0.14 s
Wall time: 0.14 s
In [5]: %time u = together(a)
CPU times: user 0.16 s, sys: 0.00 s, total: 0.16 s
Wall time: 0.17 s
In [7]: numers, denoms = zip(*((Symbol('n%d'%i),Symbol('d%d'%i)) for i in
xrange(100)))
In [8]: a = Add(*(n/d for n, d in zip(numers, denoms)))
In [9]: %time u = a.as_numer_denom4()
CPU times: user 0.61 s, sys: 0.00 s, total: 0.61 s
Wall time: 0.62 s
In [11]: %time u = together(a)
CPU times: user 0.70 s, sys: 0.00 s, total: 0.70 s
Wall time: 0.70 s
In [13]: numers, denoms = zip(*((Symbol('n%d'%i),Symbol('d%d'%i)) for i in
xrange(1000)))
In [14]: a = Add(*(n/d for n, d in zip(numers, denoms)))
In [15]: %time u = a.as_numer_denom4()
CPU times: user 88.68 s, sys: 0.01 s, total: 88.69 s
Wall time: 88.70 s
In [17]: %time u = together(a)
CPU times: user 97.71 s, sys: 0.00 s, total: 97.71 s
Wall time: 97.72 s
(those benchmarks are done with cache off, so maybe this is the
difference?).
Does together() make any other promises about the structure of the output
(...)?
Yes:
In [1]: from operator import div
In [2]: f = 1/x**2 + 1/x
In [3]: f
Out[3]:
1 1
─ + ──
x 2
x
In [4]: div(*f.as_numer_denom())
Out[4]:
2
x + x
──────
3
x
In [5]: div(*f.as_numer_denom1())
Out[5]:
2
x + x
──────
3
x
In [6]: div(*f.as_numer_denom2())
Out[6]:
2
x + x
──────
3
x
In [7]: div(*f.as_numer_denom3())
Out[7]:
2
x + x
──────
3
x
In [8]: div(*f.as_numer_denom4())
Out[8]:
2
x + x
──────
3
x
In [9]: together(f)
Out[9]:
x + 1
─────
2
x
but
In [10]: 1/(x**2 - 1) + 1/(x - 1)
Out[10]:
1 1
────── + ─────
2 x - 1
x - 1
In [11]: together(_)
Out[11]:
2
x + x - 2
────────────────
⎛ 2 ⎞
(x - 1)⋅⎝x - 1⎠
In [11]: cancel(_)
Out[11]:
x + 2
──────
2
x - 1
together() computes structural lcm of denominators (not algebraic as lcm()
does). This guarantees that the resulting denominator is minimal with
respect to the structure of the input (as I said before). It also removes
numerical contents. So, currently this is very nice that we get results on
three levels: 1) no lcm (as_numer_denom()), 2) structural lcm (together())
and 3) algebraic lcm (together() and cancel()).
It would be nice to: 1) make lcm() aware of gcd_terms() (give it symbolic
capabilities as factor() (for example) has), 2) make together() aware of
all three variations of putting fractions together and 3) make
as_numer_denom() call together() and return (numer, denom) without any
further computations.
--
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.