exp(x).as_base_exponent() -> (S.Exp1, x) (#1005)
commit73a7b69ada74ccb71df48b53605355b85def5d7d
authorKirill Smelkov <kirr@landau.phys.spbu.ru>
Sun, 10 Aug 2008 13:18:46 +0000 (10 17:18 +0400)
committerKirill Smelkov <kirr@landau.phys.spbu.ru>
Sun, 10 Aug 2008 13:18:46 +0000 (10 17:18 +0400)
tree1027f6a6dad608e3d76b4e6e55b7a9d1cc0e28a4
parent98997b9a5378f4e3578674b5780e51a2a6a1871a
exp(x).as_base_exponent()  ->  (S.Exp1, x)  (#1005)

Consider:

In [1]: exp(x).as_base_exp()
Out[1]:
⎛ x   ⎞
⎝ℯ , 1⎠

In [2]: exp(2*x).as_base_exp()
Out[2]:
⎛ x   ⎞
⎝ℯ , 2⎠

In [3]: exp(y*x).as_base_exp()
Out[3]:
⎛ x⋅y   ⎞
⎝ℯ   , 1⎠

Now let's look what we have with powers:

In [4]: (x**y).as_base_exp()
Out[4]: (x, y)

In [5]: (x**(2*y)).as_base_exp()
Out[5]: (x, 2⋅y)

I think [1], [2] and [3] are not convenient, so

  *** I propose exp(x).as_base_exp() to be (ℯ, x) ***

It seems the old behaviour was needed only for exp._eval_subs to handle cases
like:

    exp(a*expr) .subs( exp(b*expr), y )  ->  y ** (a/b)

So I've moved relevant logic into exp._eval_subs, and btw made it faster:

    e = exp(2*x)
    q = exp(3*x)

        %timeit e.subs(q, y)

old:    826 µs
new:    556 µs

Otherwise all tests pass.

Signed-off-by: Kirill Smelkov <kirr@landau.phys.spbu.ru>
Signed-off-by: Ondrej Certik <ondrej@certik.cz>
sympy/functions/elementary/exponential.py
sympy/functions/elementary/tests/test_exponential.py