Re: Pattern Matching
- To: mathgroup at smc.vnet.net
- Subject: [mg23917] Re: Pattern Matching
- From: Andrzej Kozlowski <andrzej at tuins.ac.jp>
- Date: Fri, 16 Jun 2000 00:56:57 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
Dear Hartmut One problem with questions of this kind is that the author often does not give us a really precise idea of what he wants. The result is that a number of potential solutions suggest themselves, which may work in some but not in other situations. For example, take the solution proposed by David Park, and Wagner Truppel: In[4]:= x[1] b[1] + x[1]b[2] + x[2] b[1] + x[2] b[2] /. b[n_]x[n_] -> z /. n_Integer z -> z Out[4]= z + b[2] x[1] + b[1] x[2] is fine, if that is all what Johannes wanted but; In[5]:= x[1] b[1] + x[1]b[2] + x[2] b[1] + x[2] b[2] + 3z /. b[n_]x[n_] -> z /. n_Integer z -> z Out[5]= z + b[2] x[1] + b[1] x[2] may not be quite what he had in mind. Similarly, with your solution In[6]:= Module[{virgo = True}, Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. b[n_]x[n_] :> RuleCondition[ If[virgo, virgo = False; z, Unevaluated[Sequence[]]] ]] Out[6]= z + b[2] x[1] + b[1] x[2] is fine but In[7]:= Module[{virgo = True}, ( x[1]b[1] + x[2]b[2] )y + (x[3]b[3] + x[4]b[4])v /. b[n_]x[n_] :> RuleCondition[ If[virgo, virgo = False; z, Unevaluated[Sequence[]]] ]] Out[7]= y z while it would seem to me that the answer: v z + y z would be more reasonable. In both of these cases my "global function" solution: funct[expr_Plus] := expr /. HoldPattern[Plus[Times[x[_], b[_]] ..] ] :> z; funct[(x[i_]*b[j_] /; i != j) + c_] := x[i]*b[j] + funct[c]; funct[x_] := x seems preferable, since in the above examples it gives: In[15]:= MapAll[funct, ( x[1]b[1] + x[2]b[2] )y + (x[3]b[3] + x[4]b[4])v] Out[15]= v z + y z In[16]:= MapAll[funct, x[1] b[1] + x[1]b[2] + x[2] b[1] + x[2] b[2] + 3z] Out[16]= 4 z + b[2] x[1] + b[1] x[2] But of course, as I wrote, Johannes did not really make completely clear exactly which matches were to be allowed and which not. Andrzej Kozlowski -- Andrzej Kozlowski Toyama International University, JAPAN For Mathematica related links and resources try: <http://www.sstreams.com/Mathematica/> on 00.6.15 5:27 PM, Hartmut Wolf at hwolf at debis.com wrote: > My comments below at >>>>>>>> > > Allan Hayes schrieb: >> >> Johannes, >> >> Re your first question. >> >> We get >> >> x[1] b[1] + x[2] b[2] /. >> Plus[Times[x[_], b[_]] ..] -> z >> >> b[1] x[1] + b[2] x[2] >> >> possibly because, before the matching and replacement, the left side of the >> rule is evaluated thus: >> >> Plus[Times[x[_], b[_]] ..] >> >> b[_] x[_] .. >> >> So we end up with >> >> x[1] b[1] + x[2] b[2] /. (*1*) >> (x[_] b[_]) .. -> z >> >> b[1] x[1] + b[2] x[2] >> >> We can avoid this by using HoldPattern: >> >> x[1] b[1] + x[2] b[2] /. >> HoldPattern[Plus[Times[x[_], b[_]] ..]] -> z >> >> z >> >> However it does seem odd that, in spite of (*1*), we get >> >> x * b[1] + x* b[2] /. >> (x* b[_]) .. -> z >> >> 2 z >> >> -- >> Allan >> --------------------- >> Allan Hayes >> Mathematica Training and Consulting >> Leicester UK >> www.haystack.demon.co.uk >> hay at haystack.demon.co.uk >> Voice: +44 (0)116 271 4198 >> Fax: +44 (0)870 164 0565 >> > >>>>>>>>> > > Dear Allan, > > as so often you come up with the right questions. You observed (example > simplified) > > In[35]:= h[x, x] /. x .. -> z (*2*) > Out[35]= h[z, z] > > whereas (*1*) doesn't substitute. Before coming back to that, why isn't > Out[35] > == h[z]? > > Time to go back to the Book. Although I didn't find it stated, and although we > wouldn't get an error message, all examples given in the book indicate that > the > use of Repeated in (*1*) and (*2*) isn't legal. Since Repeat[...] is > equivalent > to a Sequence the matched object must be enclosed in a head anyways, so > > In[38]:= h[x, x] /. head_[x ..] -> head[z] > Out[38]= h[z] > > works right, as well as does > > In[26]:= h[x[1] b[1], x[2] b[2]] /. head_[x[_] b[_] ..] -> head[z] > Out[26]= h[z] > > (And of course the HoldPattern version suggested by you and Andrzej > corresponds > to this syntax.) > > However this doesn't yet solve the problem as to replace only for equal > indices. > > In[47]:= x[1] b[1] + x[2] b[2] /. HoldPattern[Plus[Times[x[n_], b[n_]] ..]] -> > z > Out[47]= z + b[2] x[2] > > gives only one substitution. I would have liked to restrict the scope of the > pattern variable n_ only to Times[x[n_], b[n_]] and not to the whole sequence, > but I found no way to do that. David Park, and similarily Wagner Truppel, > proposed > > In[80]:= Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. b[n_]x[n_] -> z /. > n_Integer z -> z > Out[80]= z + b[2] x[1] + b[1] x[2] > > using iterated replacement (which is fine!). But let's try to do that within > one > stroke. Since it is easy to simply remove all elements x[n_] b[n_] > > In[88]:= Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. > p : b[n_]x[n_] :> Sequence[] > Out[88]= b[2] x[1] + b[1] x[2] > > we may try just to not remove the first occurance: > > In[125]:= Module[{virgo = True}, > Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. > b[n_]x[n_] :> > RuleCondition[ If[virgo, virgo = False; z, Unevaluated[Sequence[]]] ]] > Out[125]= > z + b[2] x[1] + b[1] x[2] > > RuleCondition is not striktly neccessary in this case, but would give a more > pleasing result if the lhs in ReplaceAll is held: then the rhs of RuleDelayed > will be evaluated *after* pattern matching and before substitution (the > Trott-Strzebonski-Hayes method; else the rhsides will be evaluated later when > the result of ReplaceAll is evaluated as the final step, which of course will > not occur if held). > > A less obfuscated method to do the same would be > > In[127]:= Module[{virgo = True}, > Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. > {b[n_]x[n_] /; First[{virgo, virgo = False}] -> z, > b[n_] x[n_] -> Sequence[]}] > Out[127]= > z + b[2] x[1] + b[1] x[2] > > where the condition is evaluated at the lhs (of Rule). > > > Finally a remark addressed to Johannes: I certainly would not try to program > that way; it is much easier (and clearer) just to seperate "diagonal" and > "off-diagonal" elements of your sum > > In[90]:= > Plus[x[1] b[1], x[1]b[2], x[2] b[1], > x[2] b[2]] /. {{b[n_]x[n_] -> Sequence[]}, {b[n_]x[m_] /; n =!= m -> > Sequence[]}} > Out[90]= > {b[2] x[1] + b[1] x[2], b[1] x[1] + b[2] x[2]} > > and then proceed with the parts as you like. > > Kind regards to everyone, > Hartmut Wolf > > > >> "Johannes Ludsteck" <ludsteck at zew.de> wrote in message >> news:8hsu3g$dh4 at smc.vnet.net... >>> Dear Group Members, >>> I would like to "find" and replace expressions with the simple >>> structure x[1] b[1]+x[2] b2]+...+x[n] b[n] >>> I tried to use the following replacement rule >>> In[27]:= x[1] b[1] + x[2] b[2] /. Plus[Times[x[_], b[_]] ..] -> z >>> >>> Out[27]= b[1] x[1] + b[2] x[2] + b[3] x[3] >>> Which didn't work (Out[27] should be z). >>> Why? >>> The following FullForm seems to give exactly the structure I used >>> in my replacement rule. >>> >>> In[17]:= >>> FullForm[x[1] b[1] + x[2] b[2] + x[3] b[3]] >>> Out[17]//FullForm= >>> Plus[Times[b[1], x[1]], Times[b[2], x[2]], Times[b[3], x[3]]] >>> >>> Even if this worked, my pattern wouldn't account for equal indices, >>> i.e. it would match x[1] b[500]+x[12] b[3], even if it shouldn't. >>> >>> Any suggestions? >>> Thanks, >>> Johannes Ludsteck >>> >>> >>> Johannes Ludsteck >>> Centre for European Economic Research (ZEW) >>> Department of Labour Economics, >>> Human Resources and Social Policy >>> Phone (+49)(0)621/1235-157 >>> Fax (+49)(0)621/1235-225 >>> >>> P.O.Box 103443 >>> D-68034 Mannheim >>> GERMANY >>> >>> Email: ludsteck at zew.de >>> >