Comment #9 on issue 2022 by asmeurer: inconsistent behaviour of subs when using non-commutative symbols
http://code.google.com/p/sympy/issues/detail?id=2022

The user should have done a subs(x, sqrt(y)) if that is what they wanted.

This is why I said "remember that the powers might not be so explicit, like exp(2*x).subs(exp(3*x), y), or something more complex than that". If you something.subs(exp(something_else*x), new_term), it doesn't look like you are doing fancy power stuff, but really you are. It shouldn't be the burden on the user to pull out the power terms just to eliminate an expression.

To give you an example of where I would use this in my integration work, say I want to integrate exp(x)*cos(x) (this isn't actually supported yet, but it will be in the future). Well, we cannot work with cos directly, we can only work with exp, log, and tan. So we do exp(x)*cos(x).subs(cos(x), (1 - tan(x/2)**2)/(1 + tan(x/2)**2) and then integrate (there are other methods to do this, but they all involve substituting cos(x) for something else before integrating). Well, this is fine, except the result you will get is 2*exp(x)*tan(x/2)/(2 + 2*tan(x/2)**2) + exp(x)/(2 + 2*tan(x/2)**2) - tan(x/2)**2*exp(x)/(2 + 2*tan(x/2)**2), instead of the exp(x)*sin(x)/2 + cos(x)*exp(x)/2 you expect. So you do ans.subs(tan(x/2), sin(x)/(1 + cos(x))), and then apply trigsimp() on it (or in the case of our current poor trigsimp, expand(factor(trigsimp(factor(cancel(a.subs(tan(x/2), sin(x)/(1 + cos(x)))))))), but that's a different issue).

Now, we have to do this for any expression that we want to integrate that contains cos(). After integrating, we don't know what tan(x/2) is going to look like in the answer (well, that's not entirely true, but work with me here). But no matter how it is, we want to eliminate it from the answer completely.

Now, this doesn't deal with the powers, you say, because it's just tan(x/2), but consider a second example, which is integrating expressions that contain functions of the form f(x)**g(x). We cannot integrate these directly either, unless f(x) == E. So the solution is to first rewrite it as exp(g(x)*log(f(x))). Now, the integral of this expression will contain exp(g(x)*log(f(x)))**integer_power terms. But if g(x) is already has some rational coefficient, then doing ans.subs(exp(g(x)*log(f(x))), f(x)**g(x)) will have to apply the y**(3/2) algorithm to work. And since the user inputed an expression with f(x)**g(x) and not exp(g(x)*log(f(x))), he expects to see only that in the answer, no matter what it takes to rewrite what is actually computed to make it look like that.

Has anyone suggested a filter option to subs where you can tell it what sort of expression to make the
substitution in? so, for example

Why not just do keyword args with hints, like expand() and others. So you would do subs(exact=True) to get only atomic substitution, or subs(all=True) to try to use all the algebraic hints that it can, or subs(integer_powers=True) to only substitute integer powers of new terms (see issue 790, comment 5), etc.

Or am I missing your point here?

But except for the proof of concept that such a replacement is possible, would anyone ever want to do
such a thing?

Maybe. It seems to me that in that case you should be using a sequence atomic (exact) substitutions, but then again, maybe that wouldn't necessarily be possible, or as easy. It's similar to Mateusz's use() function in letting you manipulate only part of an expression.

--
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