Re: Replace in Modules
- To: mathgroup at smc.vnet.net
- Subject: [mg81222] Re: Replace in Modules
- From: Szabolcs Horvát <szhorvat at gmail.com>
- Date: Sun, 16 Sep 2007 04:06:26 -0400 (EDT)
- References: <fcg3t2$rcr$1@smc.vnet.net>
Joerg Schaber wrote:
> Hi,
>
> why doesn't the following give me the square root?
>
> f[x_] := Module[{a, y},y = x;Return[FindRoot[y == a^2, {a, 1}]]]
>
> f[z] /. {z -> 2}
>
> where as
>
> f[x_] := Module[{a},Return[FindRoot[x == a^2, {a, 1}]]]
>
> f[z] /. {z -> 2}
>
> works fine?
No, it does not work fine. It gives lots of errors that you must not
ignore. If you just evaluate f[z], you get something similar to
FindRoot[y$66 == a$66^2, {a$66, 1}]
in the first case, and
FindRoot[z == a$176^2, {a$176, 1}]
in the second case. (And of course, lots of error messages.)
These are the partial results ReplaceAll operates on when you type f[z]
/. z->2 . Only the second one has 'z'. But why isn't 'y' replaced by
'z' in the first example?
In := Attributes[FindRoot]
Out = {HoldAll, Protected}
Because FindRoot has HoldAll, i.e. it processes its arguments unevaluated.
From this we can conclude that using Module is not strictly necessary
here (but it may be useful if we put other function than FindRoot in the
module). Using Return is redundant. The value of the last expression
in a CompoundExpression is always returned.
Now, what should we do about the error messages that f[z] gave?
In := f[z]
FindRoot::nlnum: The function value {-1.+z} is not a list of numbers
with dimensions {1} at {a$176} = {1.}. >>
FindRoot::nlnum: The function value {-1.+z} is not a list of numbers
with dimensions {1} at {a$176} = {1.}. >>
FindRoot::nlnum: The function value {-1.+z} is not a list of numbers
with dimensions {1} at {a$176} = {1.}. >>
General::stop: Further output of FindRoot::nlnum will be suppressed
during this calculation. >>
Of course, FindRoot[z == a^2, {a, 1}] does not work if 'z' is a
non-numerical quantity, so we change the definition of 'f' in a way that
f[z] will only evaluate if 'z' is a number:
Clear[f]
f[z_?NumericQ] := FindRoot[z == a^2, {a, 1}]
Since you used Module, you probably wanted something like this:
f[z_?NumericQ] := Module[{a}, a /. FindRoot[z == a^2, {a, 1}]]
I hope this helps,
Szabolcs