Re: Don't understand replacement rule for some functions
- To: mathgroup at smc.vnet.net
- Subject: [mg89558] Re: Don't understand replacement rule for some functions
- From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
- Date: Thu, 12 Jun 2008 06:30:53 -0400 (EDT)
- Organization: The Open University, Milton Keynes, UK
- References: <g2qhhr$8or$1@smc.vnet.net>
Mac wrote:
> Can somebody explain why the following replacement rule works
>
> In[15]:= f[x] /. x -> y
>
> Out[15]= f[y]
>
> and this one complains
>
> In[14]:= RandomReal[GammaDistribution[L, 1/L], 2] /. L -> 3
>
> During evaluation of In[14]:= RandomReal::parpos: The parameter L in \
> position 1 of GammaDistribution[L,1/L] should be positive >>
>
> Out[14]= {1.89311, 1.11748}
>
> I find it quite elegant to use replacements for complicated functions
> but I'm never quite sure whether the replacement is actually carried
> out because of such behavior.
Before evaluating an expression, Mathematica does many things [1]. Among
these things, it evaluates the arguments of the the expression *before*
applying any transformation rules. Also, keep in mind that an expression
is also a tree, so this process is applied recursively at each layer (or
level) of the tree. Then, starting from the lowest level, the
sub-expressions are evaluated in turn and any associated transformation
rules at the same level is applied.
So, the evaluation of an expression such as f[x]/.x->y (assuming f, x,
and y have no associated meaning) can be summarized as follows:
The expression f[x]/.x->y is split in two parts: f[x] and x->y.
Before applying the rule x->y, Mathematica evaluates the argument (i.e.
x) of f[x]. Since x is an atomic expression with no value attached to
it, it evaluates to itself, that is x.
So, now we are left with f[x] to which the rule x->y is going to be
applied. Having done so, f[x] is transformed into f[y] and only now
Mathematica is going to evaluate this expression f[y]. Since f has no
definition attached to it, the result of the evaluation is f[y] itself.
Wow, I hope I have not confused you insofar!
Following the same procedure, this time with the second expression,
RandomReal[GammaDistribution[L, 1/L], 2] /. L -> 3
we now understand that Mathematica attempts to evaluate first (there is
a mechanism to control this, see below *) the arguments provided to
RandomReal, that is 2, which evaluates to 2, and GammaDistribution[L,
1/L] which evaluates to itself since GammaDistribution required numeric
arguments (as well as RandomReal, thus the warning message).
Therefore, the result of this preprocessing, is the expression
RandomReal[GammaDistribution[L, 1/L], 2]
to which Mathematica is going to apply the rule L->3 that was put on
hold. Having applied the rule, the expression becomes
RandomReal[GammaDistribution[3, 1/3], 2]
expression which is now perfectly valid and RandomReal is going to be
evaluated, which yields the two random numbers you got after the warning
message.
Consequently, as a rule of thumb, one should "attach" any transformation
rules as close as possible of the relevant function or part of the
expression. For instance,
In[1]:= RandomReal[GammaDistribution[L, 1/L] /. L -> 3, 2]
Out[1]= {0.382089, 0.471758}
Or, one can use the With[] construct as in
In[2]:= With[{L = 3}, RandomReal[GammaDistribution[L, 1/L], 2]]
Out[2]= {1.22402, 0.395845}
Well, I hope I have shed more light than obscurity on the process :-)]
Best regards,
- Jean-Marc
[1] "The Main Loop",
http://reference.wolfram.com/mathematica/tutorial/TheMainLoop.html
* to see the attributes of a function, one can use Attributes[], and
SetAttributes[] to set some specific attributes, such as HoldFirst that
delays the evaluation of the first argument until the execution of the
body of the function.