Maybe someone can explain to me why Replace
gives a different answer than ReplaceAll
, even though I am using one rule, and, I think, I have one expression.
According to the documentation:
ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to
the next part of expr. The first rule that applies to a particular part is used; no
further rules are tried on that part, or on any of its subparts
and for Replace
A list of rules can be given. The rules are tried in order. The result of the first
one that applies is returned. If none of the rules apply, the original expr is
returned.
I have this expression:
z/(0.5 -1.4 z+z^2)
and this one rule
z -> Exp[I*w]
The following input
Clear[z]
hz = z/(0.5 - 1.4 z + z^2);
Replace[hz, z -> Exp[I*w]]
ReplaceAll[hz, z -> Exp[I*w]]
yields this result:
z/(0.5 -1.4 z+z^2) (*from Replace*)
E^(I w)/(0.5 -1.4 E^(I w)+E^(2 I w)) (*from ReplaceAll*)
So, ReplaceAll
did the job I expected, but not Replace
. The only thing I think I am missing here, is what makes Parts of an expression. So maybe hz is not 'one' expression? Ok, fine, but it should then have been able to apply the rule at least to one part of it. But it did not do any replacement anywhere
FullForm[hz]
Times[z,Power[Plus[0.5`,Times[-1.4`,z],Power[z,2]],-1]]
Isn't hz one expression? If not, how many parts does it have? Is it the number of leaves at the end of the graph generated by TreeForm[hz]
? If so, then I see 3 'z' in there, and Replace[]
should then have replaced one of them
I always used /.
without thinking about it, which is the same as ReplaceAll
, but now I used Replace[]
thinking is was the same as /.
, I found this and noticed the different functions.
(so many functions to learn, so little time :)
In fact,
Replace
andReplaceAll
are not the same. You can think ofReplace
as a more precise version, since withReplace
you can specify the levels in expression on which you want the replacements to happen. The difference here is somewhat similar to that betweenMap
andMapAll
, except the subtlety thatReplaceAll
does not work depth-first (see below). Another difference, also rather subtle, is thatReplace
takes theHeads
option, whileReplaceAll
does not, which makesReplace
yet more precise thanReplaceAll
.By default,
Replace
works only at level 0, which is, entire expression. Yourz
is deeper however:If you use the level specification for
Replace
, you can achieve an effect similar to, but not always the same as that ofReplaceAll
:The difference between
Replace
with lev.spec{0,Infinity}
andReplaceAll
is that the former acts depth-first, sub-expressions before expressions, while the latter works from larger expressions to their parts. It is discussed in more detail e.g. here. One example where this difference was used to one's advantage can be found in this post.Coming back to default behavior of
Replace
, which operates on entire expression: it is very useful when you want to transform only the entire expression, but none of its parts (which may accidentally match the pattern in your rule). One example of such application ofReplace
is here.I think the relevant bit of the documentation for
Replace
is: "applies a rule or list of rules in an attempt to transform the entire expression expr. " i.e., to transform the entire expression. Thus,would transform
z
toExp[I*w]
, but your example fails because the rule does not match the entire expression.Note that
Replace
takes an argumentlevel spec
; so to operate on the end leaves of your tree, trygiving