Re: Re: Algebra on complex expressions: Collect
- To: mathgroup at smc.vnet.net
- Subject: [mg15255] Re: [mg15244] Re: [mg15225] Algebra on complex expressions: Collect
- From: Andrzej Kozlowski <andrzej at tuins.ac.jp>
- Date: Mon, 28 Dec 1998 02:37:52 -0500
- Sender: owner-wri-mathgroup at wolfram.com
It seems that Daniel Lichtblau's complexCollect (from Karl Woll's message) compbined with using the option TargetFunctions -> {Re,Im} (which I failed to notice) gives you equivalent of loading the ReIm package and using my complexcollect, but without requiring declaring variables as real. Of course the "problem" of the ordering of symbols remains: In[1]:= complexCollect[expr_, var_] := Module[{myI, e2, v2}, {e2, v2} = {expr, var} /. Complex[a_, b_] -> a + myI*b; Collect[e2, v2] /. myI -> I] In[2]:= complexCollect[P+E*I+a+b*I,I] Out[2]= a+I (b+E)+P Also, my attempt to redefine Abs at the end of my message is not needed (because of the option TargetFunctions -> {Re,Im}) and in any case it fails for expressions of the form 2+3I+a+b*I (where a and b are meant to be real). The quickest way to make absolute value of a+ b*I return Sqrt[a^2+b^2] is to use ComplexExpand[Abs[a+b*I],TargetFunctions->{Re,Im}]. This has the virtue of working correctly for experssions like 2+3I+a+b*I. (Such expressions present a problem for simple minded pattern matching constructions since they have a somewhat complicated FullForm: In[3]:= FullForm[2+3I+a+b*I] Out[3]//FullForm= Plus[Complex[2,3],a,Times[Complex[0,1],b]] ) Thus my modified Abs will not work on 2+3I+a+b*I In[4]:= Abs[2+3*I+a+b*I] Out[4]= Abs[(2+3 I)+a+I b] While In[5]:= ComplexExpand[Abs[2 + 3 I + a + b I], TargetFunctions -> {Re, Im}] Out[5]= 2 2 Sqrt[(2 + a) + (3 + b) ] The correct modification of Abs to use witht the ReIm package (if you want to use it!) is of course: Unprotect[Abs] Abs[z_]:=Sqrt[Re[z]^2+Im[z]^2] Protect[Abs] On Sun, Dec 27, 1998, Andrzej Kozlowski <andrzej at tuins.ac.jp> wrote: >I am not quite sure why you find the existing Re and Im functions >unsatisfactory, but here are a few comments which may be helpful. I >assume you want to be able to deal both with numberic complex numbers, >like 2+3I and symboloc ones like a+b*I, where a and b are meant to be >real. It is useful first to load the package > ><<Algebra`ReIm` > > >This make sit possible to declare certain symbols to be real, e.g.: >a/:Im[a]=0;b/:Im[b]=0;c/:Im[c]=0;d/:Im[d]=0; declares a, b, c, d to be >real. > >Mathematica can now find real and imaginary parts of symboloc >expressions like: > >In[1]:= >Im[(a+b*I)/(c+d*I)] >Out[1]= > b c a d >------- - ------- > 2 2 2 2 >c + d c + d > > >You can if you want define your own complexcollect function: > >In[2]:= >complexcollect[x_]:=Re[x]+I*Im[x] > >This will work well in the above example: > >In[2]:= >complexcollect[(a+b*I)/(c+d*I)] >Out[11]= > a c b d b c a d >------- + ------- + I (------- - -------) > 2 2 2 2 2 2 2 2 >c + d c + d c + d c + d > > >but now always, e.g. > >In[3]:= >complexcollect[3+4I+Pi+E*I] >Out[3]= >3 + I (4 + E) + Pi > >The point is that Mathematica will order the symbols according to its >built in ordering principle and, depending on the names of your >symbols, the real numbers may be separated by the complex part. Of >course you can make things look right by choosing the letters you use >for your real and imaginary parts carefully, but sometimes, as in the >above example, you have no choice! I do not know of any simple way of >solving this "problem", if it is a problem, though it would be easy >enough to do if you were only concerned with the expression "looking >right". > >Finally, if you decide to use ComplexExpand you will get: > >In[4]:= >ComplexExpand[(a+b*I)/(c+d*I)] >Out[4]= > a c I b c I a d b d >------------- + ------------- - ------------- + ------------- > 2 2 2 2 >Abs[c + I d] Abs[c + I d] Abs[c + I d] Abs[c + I d] > >Abs disregards the fact that we declared c and d to be real. One can >modify Abs to pay attention to this: > >In[5]:= >Unprotect[Abs] >Abs[a_+b_*I]/;(Im[a]==0&&Im[b]==0):=Sqrt[a^2+b^2] Protect[Abs] > >Now, > >In[6]:= >ComplexExpand[(a+b*I)/(c+d*I)] >Out[6]= > a c I b c I a d b d >------- + ------- - ------- + ------- > 2 2 2 2 2 2 2 2 >c + d c + d c + d c + d > >I hope this is of some help. If any one knows of a better way to answer >this question I would like to hear of it myself > >On Wed, Dec 23, 1998, Ross, Sean <rosss at plk.af.mil> wrote: > > >D>Does anyone know a way to have a Collect -like function work on >>expressions with complex numbers? If I have an expression with "x" in >>it, I can use Collect[expr,x], but if I have an expression with "I" in >>it, Collect[expr,I] does not separate the expression into a part with >>and without "I" which would be equivalent to separating the expression >>into real and imaginary parts given all symbols were real. >> >>The RealOnly package does not seem to apply as it excludes imaginary >>numbers alltogether. ComplexExpand results in a ridiculous amount of >>complexity and is worse than nothing for this purpose. Expanding and >>multiplying numerator and denominator separately by the complex >>conjugate of the denominator is tedious to do manually and results in >>the same problem of no way to neatly separate the real and imaginary >>parts of a symbolic expression given that all symbols are real. >> >>Thanks. >> >>Sean Ross >> >>Please reply to rosss at plk.af.mil as I no longer subscribe to the >>mathgroup. >> > > >Andrzej Kozlowski >Toyama International University >JAPAN >http://sigma.tuins.ac.jp/ >http://eri2.tuins.ac.jp/ > Andrzej Kozlowski Toyama International University JAPAN http://sigma.tuins.ac.jp/ http://eri2.tuins.ac.jp/ Andrzej Kozlowski Toyama International University JAPAN http://sigma.tuins.ac.jp/ http://eri2.tuins.ac.jp/