On Tue, Jul 28, 2009 at 7:48 PM, Aaron S. Meurer<asmeu...@gmail.com> wrote: > > This is the relevant code from Mul.flatten() (line 305 in core/mul.py): > if len(c_part)==2 and c_part[0].is_Number and c_part[1].is_Add: > # 2*(1+a) -> 2 + 2 * a > coeff = c_part[0] > c_part = [Add(*[coeff*f for f in c_part[1].args])] > > So it autocombines only if there are exactly two terms, and the first > one is a Number and the second one is an Add. Mul combines > ieteravely, so this combines more often than you would think. But > because of the iterative nature of it, it can depend on the order of > the terms! > > >>> 2*(x+y)*z > z⋅(2⋅x + 2⋅y) > >>> (x + y)*2*z > z⋅(2⋅x + 2⋅y) > >>> z*(x + y)*2 > 2⋅z⋅(x + y) > >>> z*2*(x + y) > 2⋅z⋅(x + y) > >>> 2*z*(x + y) > 2⋅z⋅(x + y) > > This is also related to issue 1497. -(x + y)/z combines into (-x - y)/ > z, but (x + y)/-z is left alone. > > And here are the below tests in actual Maple. They seem to be the > same as Matlab with Maple. I also included my ones from above: > > exp1:=x*(x-y); > x (x - y) > > exp2:=x*x-x*y; > 2 > x - x y > > exp3:=4*(x-y); > 4 x - 4 y > > exp4:=4*x-4*y; > 4 x - 4 y > > factor(exp1); > x (x - y) > > factor(exp2); > x (x - y) > > factor(exp3); > 4 x - 4 y > > factor(exp4); > 4 x - 4 y > > 2*(x+y)*z; > 2 (x + y) z > > (x + y)*2*z; > 2 (x + y) z > > z*(x + y)*2; > 2 (x + y) z > > z*2*(x + y); > 2 (x + y) z > > 2*z*(x + y); > 2 (x + y) z > > factor(z*(2*x + 2*y)); > 2 (x + y) z > > So it looks like Maple only does it when there are two terms and one > is a number and the other is an Add. I think this is what was > intended with the above code, but because of the iterative nature of > Mul, it is impossible to tell how many terms there really are. I > think this is another example of why it would be better for Mul and > Add to somehow wait until iterative building is complete until > autosimplifying (such as with handler logic). > > I don't see how you could have 4*(x + y) sometimes distribute and > sometimes not. What would be the rules for when it is supposed to > distribute and when it is supposed to stay? There is no way for Mul > to tell if the user has input 4*(x + y) or if it has been returned > from factor(). And even if it could, if the user did something like a > = factor(4*x + 4*y), and then print a, it would just go back to 4*x + > 4*y because the print a would be "user input".
There is a way around it, as I pointed out, if you do this: In [3]: Mul(4, x-y, evaluate=False) Out[3]: 4⋅(x - y) it stays as it is. I am not saying I like it, especially that Mul just can't "hold it" together without "evaluate=False". > > I vote to remove it. As I pointed out above, it doesn't even work > consistently, and cannot as long as Mul.flatten() is called > iteratively. Several tests will have to be fixed (it breaks Sum if I > remember correctly. Probably others too). You may be able to just > apply expand_mul to the relevant code blocks, or you may need to write > a special function that only distributes in the way that is presently > automatic. Or you may need to just restructure whatever algorithm to > take non-distribution into account. It should not be a big problem to just remove the automatic simplification of 4*(x+y). I think we should do it. Ondrej --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to sympy@googlegroups.com To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sympy?hl=en -~----------~----~----~----~------~----~------~--~---