Re: Pattern Matching Problem
- To: mathgroup at smc.vnet.net
- Subject: [mg43407] Re: Pattern Matching Problem
- From: John Tanner <john at janacek.demon.co.uk>
- Date: Fri, 29 Aug 2003 07:16:10 -0400 (EDT)
- References: <bihp1v$b3u$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
In article <bihp1v$b3u$1 at smc.vnet.net>, "Ersek, Ted R" <ErsekTR at navair.navy.mil> writes >Consider the following: > >In[1]:= > ClearAll[f,a,b,c,w,x,y,z]; > expr=a+b+c+f[w,2]+f[w,3]+x+f[x,2]+f[x,3]+y+f[y,2]+f[z,2]; > > >Can somebody suggest a general way to seperate the terms above into like >groups. By "like" I mean having the same second argument for (f). So for >this example I want to get > >{a+b+c+x+y, f[w,2]+f[x,2]+f[y,2]+f[z,2], f[w,3]+f[x,3]} > >The pattern matcher should be able to do this because Plus has attributes >Flat and Orderless. However I can't find a way to make it happen. > >------------------- >Thanks, > Ted Ersek > ----------------------------------------------------------------------- --------------------------------- If you are sure you have a simple sum, then use Cases or equivalent on expr itself: In[3]:=Plus @@ Cases[expr, _Symbol] Out[3]:=a+b+c+x+y In[4]:= Plus @@ Cases[expr, _[_, 2]] Out[4]:=f[w,2]+f[x,2]+f[y,2]+f[z,2] This procedure is "slightly unsafe", so it is probably better to do a bit of expanding first (hopefully this catches most problems, but such problem cases will need extra Cases[]). Fortunately the List generation works even for negative valued terms, but to be general beware of sums in the denominator(s) of any term(s)!: In[5]:= exprlist=ExpandAll[expr] /. Plus -> List Out[5]:={a,b,c,x,y,f[w,2],f[w,3],f[x,2],f[x,3],f[y,2],f[z,2]} In[6]:= Cases[exprlist, _[_, 2]] Out[6]:={f[w, 2], f[x, 2], f[y, 2], f[z, 2]} so finally (if a little inelegant and not really "general": feel free to improve!): In[7]:=Prepend[ (Plus @@ Cases[exprlist,_[_,#]])& /@ {2,3}, Plus @@ Cases[exprlist,_Symbol]] Out[7]:={a+b+c+x+y, f[w,2]+f[x,2]+f[y,2]+f[z,2], f[w,3]+f[x,3]} There are various other ways of improving the use of the list: possibly Union[Part[#,-1]& /@ Cases[exprlist,_[_,_]]] to generate the list of the values of the second argument, or Split[ Sort[Cases[exprlist,_[_,_]],OrderedQ[{Part[#1,-1],Part[#2,-1]}]&], Part[#1,-1]==Part[#2,-1]&] which goes some way towards being more general. [use these at your own risk..] There is also a "really risky" but very direct alternative, good luck if you want to try to make it general: In[8]:=DeleteCases[expr,#]& /@ {_[_,_],_Symbol | _[_,3],_Symbol | _[_,2]} Out[8]:={a+b+c+x+y, f[w,2]+f[x,2]+f[y,2]+f[z,2], f[w,3]+f[x,3]} -- from - John Tanner home - john at janacek.demon.co.uk mantra - curse Microsoft, curse... work - john.tanner at baesystems.com I hate this 'orrible computer, I really ought to sell it: It never does what I want, but only what I tell it.