Re: Apply a rule to an expression only once

*To*: mathgroup at smc.vnet.net*Subject*: [mg116358] Re: Apply a rule to an expression only once*From*: Guido Walter Pettinari <coccoinomane at gmail.com>*Date*: Fri, 11 Feb 2011 04:20:16 -0500 (EST)

Dear Andrzej, thank you for your answer. Your example works indeed, but I would rather prefer not to modify my original rule, which is much more complex than the one I quoted in the example. I want the rule to stay the most general as possible, since it is used elsewhere in my package and a redefinition will break it. My package transforms mathematical equations from a real [x,y,z] space to a Fourier [kx,ky,kz] space. The main ingredient is a rule that applies the necessary derivative & coordinate transformations on single terms (e.g. Derivative[1,0,0][ f [x,y,z] ] -> I kx f [kx,ky,kx] ). This works perfectly fine on linear terms, but things get more involved when dealing with quadratic terms. In fact, the Fourier transform of a quadratic term, say f [x,y,z] g [x,y,z], is a convolution term of the form C [ f [k1,k2,k3] g[q1,q2,q3] ], where C[] denotes a convolution integral over k1,k2,k3 and q1,q2,q3. Aside from mathematical details, I would like to know a way to change the expression: expr = f [ x ] g [ x ] h [ x ] ..... into f [ k1 ] g [ k2 ] h [ k3 ] .... by applying in a proper way the following rule: rule[k_] := f_@x :> f@k . No redefinitions of the rule are allowed :-) I thought that a solution could be an option for Replace (say, OnlyFirst) that applies the rule only to the first occurrence of the pattern: expr // Replace [ #, rule[k1], OnlyFirst->True ]& // Replace [ #, rule[k2], OnlyFirst->True ]& // Replace [ #, rule[k3], OnlyFirst->True ]& // ... but I do not know how to implement the "OnlyFirst" bit. Please note that (i) I do not care which function gets which dependence, e.g. f[k2]g[k3]h[k1] is equally good for me, and (ii) I do not know the names of the functions, I only recognize them by their coordinate dependence (usually x,y,z). Thank you again for your consideration! Best regards, Guido On 10 Feb 2011, at 12:53, Andrzej Kozlowski wrote: > One simple way that appears to achieve what you want (or seem so) is to use Replace instead of ReplaceAll. After all, you do not want to "replace all", do you? > > So > > expr = f a + f b; > > rule = f p_ + x_ :> f[p] + x > > Replace[expr, rule] > > f[a] + b*f > > ? > > Andrzej Kozlowski > > On 10 Feb 2011, at 19:22, Guido Walter Pettinari wrote: > >> Hello group! >> >> Does anybody know how to apply a rule to an expression only once? >> In other words, is it possible to tell ReplaceAll to stop after the >> first application of a rule? >> >> Simple example: >> >> expr = f a + f b; >> rule = f p_ :> f [p]; >> ReplaceAll [ expr, rule ] >> >> The output, as expected, is: >> f [a] + f [b] >> >> However, what I want is something like: >> >> ReplaceAll [ expr, rule, OnlyFirst -> True ] >> >> that gives the output >> >> f [a] + f b. >> >> My simple example can be solved by using ReplacePart, but alas it is >> not the kind of solution I am looking for. >> >> Thank you for your consideration! >> >> Best regards, >> >> Guido W. Pettinari >> >> P.S. I found a temporary solution by using a pattern test at the time >> of rule definition, i.e. >> >> rule = f p_ /; matchFirst[] :> f [p], >> >> with >> >> matchFirst [] := Module [ { }, >> If [ TrueQ@$alreadyMatched, False, $alreadyMatched = True; True] >> ], >> >> but this does not satisfy me since (i) I do not want to alter the rule >> definition, and (ii) I have to update the global variable >> $alreadyMatched every time I want to use the trick. >> >> >

**Follow-Ups**:**Re: Apply a rule to an expression only once***From:*Daniel Lichtblau <danl@wolfram.com>

**Re: Apply a rule to an expression only once***From:*Fred Simons <f.h.simons@tue.nl>