Re: Apply a rule to an expression only once

*To*: mathgroup at smc.vnet.net*Subject*: [mg117080] Re: Apply a rule to an expression only once*From*: Guido Walter Pettinari <coccoinomane at gmail.com>*Date*: Wed, 9 Mar 2011 06:59:39 -0500 (EST)*References*: <ij2v15$7vn$1@smc.vnet.net> <ij5mp0$ji5$1@smc.vnet.net>

Thank you very much for all the answer! All of them were very interesting and taught me something. In the end I adopted Ray's solution, with a slight modification in order to prevent an error if the rule doesn't apply: If [ Position[expr, rule[[1]]] === {}, expr, MapAt[ReplaceAll[#, rule] &, expr, Position[expr, rule[[1]]][[1]]]] ] Cheers, Guido On Feb 12, 10:18 am, Ray Koopman <koop... at sfu.ca> wrote: > On Feb 11, 1:20 am, Guido Walter Pettinari <coccoinom... at gmail.com> > wrote: > > > > > > > > > > > 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). > > replaceFirst[expr_, rule_] := MapAt[ Replace[#, rule]&, > expr, Position[expr,rule[[1]]][[1]]] > > expr = f[x] g[x] h[x]; > > rule[k_] = f_[Except[k1|k2|k3]] :> f[k]; > > Fold[replaceFirst, expr, rule/@{k1,k2,k3}] > > f[k1] g[k2] h[k3]