Re: PowerExpand in version 6

*To*: mathgroup at smc.vnet.net*Subject*: [mg85854] Re: PowerExpand in version 6*From*: Andrzej Kozlowski <akoz at mimuw.edu.pl>*Date*: Mon, 25 Feb 2008 07:35:41 -0500 (EST)*References*: <fpoonm$1ev$1@smc.vnet.net> <b444f402-e3c3-4f84-b157-ea691d5c54c6@q70g2000hsb.googlegroups.com>

Dear Sasha Thank you very much for your very helpful and thorough explanations. They indeed answer my questions but I have to admit, they also leave me somewhat worried. The reason is that what happened to PowerExpand can be seen as the first signs of Mathematica beginning to break down under the weight of legacy code. Being not very young myself I have seen this sort of thing happen to other "old" (more than a decade) programs and I hope Mathematica does not go this way. To tell the truth, it seems to me it was an absolutely dreadful (I nearly wrote "criminal") decision to implement the new PowerExpand in this way, in order to preserve compatibility with past code. What should have been done was exactly what was done with Random, a new function with a new name (e.g. "ExpandPowers") should have been introduced while the old one retained for the sake of compatibility. Now something terrible has happened - the user is lead to believe that Assuming and Assumptions-> are always equivalent and it is only a matter of choice which one to use but the truth is that he can never be sure if his code containing Assuming will work as intended and has to decide everything on a case by case basis. This effectively makes Assuming unusable. Even the second problem, caused by Refine, is worrying. What happens is that when you use PowerExpand[Sqrt[x*y], x>0&&y>0] first Sqrt[x*y] is expanded and then put back (by Refine) and all of that happens in a way totally non-transparent to the user. Again, this results in total unpredictability. The user can never be sure if PowerExpand will expand powers or will not. These unpredictabilities add up, so that I would now avoid using the new PowerExpand in any code since the trouble of checking what it will do in individual cases seems to exceed its benefits. Fortunately it is only one function but I think it is important that it should not become a precedent for future development of Mathematica. Obviously the way to proceed when certain oldish functions are replaced by more sophisticated version is the way that was used in the case of Random, RandomInteger, RandomReal etc, than the approach adopted in the case of PowerExpand. With best regards Andrzej On 25 Feb 2008, at 05:03, sashap wrote: > Dear Andrzej, > > Assuming works by setting $Assumptions, and this has the desired > effect for most of the functions, because their Assumptions options > is defaulted to $Assumptions. > > Here is a list of all System` context symbols with Assumptions option: > > In[184]:= ToExpression /@ > Quiet[Select[Names["System`*"], > MemberQ[ToExpression[#, StandardForm, > Options[Unevaluated[#]] &][[All, 1]], Assumptions] &]] > > Out[184]= {ExpectedValue, FourierCosTransform, FourierSinTransform, \ > FourierTransform, FullSimplify, FunctionExpand, Integrate, \ > InverseFourierCosTransform, InverseFourierSinTransform, \ > InverseFourierTransform, LaplaceTransform, Limit, PiecewiseExpand, \ > PossibleZeroQ, PowerExpand, Refine, Residue, Series, Simplify} > > We now select the one where Assumptions is not set to $Assumptions: > > In[185]:= Select[{#, Options[#, Assumptions]} & /@ %, > FreeQ[#, HoldPattern[$Assumptions]] &] > > Out[185]= {{PowerExpand, {Assumptions -> Automatic}}} > > This was done for backwards compatibility. Unfortunately resetting > this option globally might not be a very good idea, because it would > change the behavior of some of internal code which uses PowerExpand. > > As to other issues you point out to, they follow from behavior of > Refine: > > In[193]:= res = PowerExpand[Sqrt[x*y], Assumptions -> True] > > Out[193]= E^( > I \[Pi] Floor[ > 1/2 - Arg[x]/(2 \[Pi]) - Arg[y]/(2 \[Pi])]) Sqrt[x] Sqrt[y] > > In[195]:= Refine[res, Assumptions -> x > 0] > > Out[195]= Sqrt[x] Sqrt[y] > > In[196]:= Refine[res, Assumptions -> x > 0 && y > 0] > > Out[196]= Sqrt[x y] > > In[197]:= Refine[res, Assumptions -> x > 0 && Arg[y] == 0] > > Out[197]= Sqrt[x] Sqrt[y] > > Oleksandr Pavlyk > > > On Feb 23, 3:24 am, Andrzej Kozlowski <a... at mimuw.edu.pl> wrote: >> The ancient function PowerExpand, indispensable before the >> Assumptions mechanism was introduced in version 4 of Mathematica, >> became a bit of an embarrassment in later versions and there were >> even >> voices, I can remember, arguing that it ought to be deprecated. >> Instead, PowerExpand was modified in version 6 by making it possible >> to use the Assumptions mechanism with it and this giving this almost >> dead function a new lease of life. This is indeed very nice when it >> works, but unfortunately the implementation still leaves some things >> to be desired. >> >> The main example in the documentation is: >> >> PowerExpand[Sqrt[x*y], Assumptions -> True] >> >> E^(I*Pi*Floor[-(Arg[x]/(2*Pi)) + 1/2 - Arg[y]/(2*Pi)])* >> Sqrt[x]*Sqrt[y] >> >> which gives a general expansion that is valid for all x and y. But >> note that the normally equivalent form Assuming will not work: >> >> Assuming[True, PowerExpand[Sqrt[x*y]]] >> Sqrt[x]*Sqrt[y] >> >> In fact Assuming is simply ignored and the answer returned is the >> same >> as that given by PowerExpand without any assumptions. This is >> disappointing for those (like myself) who prefer to use Assuming to >> Assumptions -> , but may perhaps be a matter of deliberate design >> (why?). But the next problem is certainly a bug. >> >> First note that: >> >> PowerExpand[Sqrt[x*y], Assumptions -> x > 0] >> Sqrt[x]*Sqrt[y] >> >> which is quite correct but suppose we make an even stronger >> assumption: >> >> PowerExpand[Sqrt[x*y], Assumptions -> x > 0 && y > 0] >> Sqrt[x*y] >> >> We do not get the expansion we should obtain. Curiously we can get >> the >> correct expansion if we use a more complicated way of stating the >> same >> assumption, e.g. >> >> PowerExpand[Sqrt[x*y], Assumptions -> x > 0 && Arg[y] == 0] >> Sqrt[x]*Sqrt[y] >> >> or >> >> PowerExpand[Sqrt[x*y], Assumptions -> x > 0 && Re[y] > 0] >> Sqrt[x]*Sqrt[y] >> >> Andrzej Kozlowski >