Mathematica 9 is now available
Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2007
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Replace in Modules

  • To: mathgroup at smc.vnet.net
  • Subject: [mg81263] Re: Replace in Modules
  • From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
  • Date: Tue, 18 Sep 2007 00:35:13 -0400 (EDT)
  • Organization: The Open University, Milton Keynes, UK
  • References: <fcg3t2$rcr$1@smc.vnet.net>

Joerg Schaber wrote:

> 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?

Well, I would not say that the second expression is working fine since 
several error messages are displayed during the evaluation process and 
the answer is a rule (nothing wrong here) that contains the name of a 
local symbol (something is terribly wrong here).

Of course, if you disregards these two major issues and if you do not 
need to use the result anyway (otherwise you must add some additional 
code that is going to convert the local name to a global one that can be 
use in subsequent evaluation), the function can be deemed as successful 
in its attempt to compute sqrt(2).

In[1]:= f[x_] := Module[{a}, Return[FindRoot[x == a^2, {a, 1}]]]
f[z] /. {z -> 2}

During evaluation of In[1]:= FindRoot::nlnum: The function value \
{-1.+z} is not a list of numbers with dimensions {1} at {a$65} = \
{1.}. >>

During evaluation of In[1]:= FindRoot::nlnum: The function value \
{-1.+z} is not a list of numbers with dimensions {1} at {a$65} = \
{1.}. >>

During evaluation of In[1]:= FindRoot::nlnum: The function value \
{-1.+z} is not a list of numbers with dimensions {1} at {a$65} = \
{1.}. >>

During evaluation of In[1]:= General::stop: Further output of \
FindRoot::nlnum will be suppressed during this calculation. >>

Out[2]= {a$65 -> 1.41421}

(Note that *Return* is not needed: the value of the last expression to 
be evaluated is returned.)

Having said that, what explains the differences in behavior is /not/ 
*Module* but operator _precedences_ (or priorities if you want). Let see 
how the following expression is evaluated

When Mathematica evaluates the expression f[z] /. z -> 2, it starts from 
the left, that is it evaluates first f[z], only then it applies the 
transformation rule to the result returned by the evaluation of f[z].

So, using the first definition of f[x] and assuming that z has no global 
value, we have the following sequence: x is replace by z as the formal 
name of the argument, y takes the value of z that is 'z' since at this 
stage z has no value, then FindRoot is called with some argument which 
does not have any numeric value (the infamous -1 + z in the error 
messages) so it complains and returns unevaluated.

This unevaluated form of FindRoot is passed on to the replacement rule z 
-> 2 which has nothing to replace since no z are present in the 
expression; therefore the unevaluated FindRoot is what is returned as 
final answer.

Now, if z has a global value before evaluating the expression f[z] /. z 
-> 2, as you can see below, none of them work as expected (though the 
results are expected from Mathematica point of view).

In[6]:= z = 5;
f[x_] := Module[{a, y}, y = x; Return[FindRoot[y == a^2, {a, 1}]]]
f[z] /. {z -> 2}

Out[8]= {a$181 -> 2.23607}

In[9]:= z = 9;
f[x_] := Module[{a}, Return[FindRoot[x == a^2, {a, 1}]]]
f[z] /. {z -> 2}

Out[11]= {a$187 -> 3.}

The expected numerical value can be obtained by putting the replacement 
rule inside the square brackets (which is equivalent to evaluating f[2], 
indeed).

In[12]:= z = 5;
f[x_] := Module[{a, y}, y = x; Return[FindRoot[y == a^2, {a, 1}]]]
f[z /. z -> 2]

Out[14]= {a$193 -> 1.41421}

In[15]:= z = 9;
f[x_] := Module[{a}, Return[FindRoot[x == a^2, {a, 1}]]]
f[z /. z -> 2]

Out[17]= {a$199 -> 1.41421}

Finally, a correct way to code your function could be

f[(z_)?NumericQ] := Module[{a}, a /. FindRoot[z == a^2, {a, 1}]]

since you do note return any spurious local name into the global context.

Regards,
-- 
Jean-Marc



  • Prev by Date: Re: Defining a Function with an Indeterminate Number of Arguments
  • Next by Date: Re: LegendreP error (bug?) in Mathematica
  • Previous by thread: Re: Replace in Modules
  • Next by thread: Exporting 3D vector graphics