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.