Re: Re: Compile
- To: mathgroup at smc.vnet.net
- Subject: [mg45337] Re: [mg45333] Re: Compile
- From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
- Date: Thu, 1 Jan 2004 05:54:30 -0500 (EST)
- References: <200312310823.DAA08660@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
First, I have to admit that my early, not carefully considered response to Maxim's examples was quite wrong. I failed to see that a lot more is going on under the hood than I at first suppose. I still stand by the assertion that all this is quite irrelevant. Maxim loves pathological examples because he thinks they prove some point he is trying to make (I am not even really sure what it is). In fact none of these examples would ever arise in practice: any moderately knowledgeable user of Mathematica knows that if you want to use the compiled->True (default) option setting in Plot your function has to be written out in-line or you have to use Evaluate. Moreover, his second example makes no sense at all except as an attempt to produce something mystifying, that will than allow him to suggest that something is badly wrong. But any way, once the reservation that all this has no relevance whatever to any practical usage of Mathematica has been made, we can try to play a little detective game, that may be perhaps even interesting as "art for art's sake". So first of all, let's not that Maxim's first example Module[{subs = x -> x^2}, Plot[x /. subs, {x, 0, 1}, Compiled -> True] ] Module[{subs = x -> x^2}, Plot[x /. subs, {x, 0, 1}, Compiled -> False] ] was in a way an exception, and that mislead me. The two examples produce different answers, and the second one gives the same output as when you use Evaluate in Plot, but it actually need not always be so and in fact is a rather special case. Just change it a little: Module[{subs = x -> x^(1/3)}, Plot[x^3 /. subs, {x, 0, 1}, Compiled -> True] ] Module[{subs = x -> x^(1/3)}, Plot[x^3 /. subs, {x, 0, 1}, Compiled -> False] ] and you see no difference, both cases giving the cubic curve, while the correct approach, which any competent Mathematica user (except of course Maxim) would use: Module[{subs = x -> x^(1/3)}, Plot[Evaluate[x^3 /. subs], {x, 0, 1}, Compiled -> True] gives a straight line. In fact, even in case when you do not Compile but when your function is not defined "in line" you should generally use Evaluate, for obvious reasons which have nothing to do with compilation. (This demonstrates the practical uselesness of both of Maxim's examples). Secondly, you can see exactly what happens in all these cases if you use Trace[ , TraceInternal->True] And when you examine this you come to the following conclusion: that with the setting Compiled->False everything is predictable and there is no difficulty in explaining it. With the setting Compiled->True (without Evaluate), behaviour is more difficult to predict. But that is not actually surprising, because using the setting Compile->True in such cases without Evaluate is simply bad or incompetent Mathematica programming, contrary to the documentation and when you do that you can't complain that funny things happen (not that this sort of argument will ever stop Maxim). Now let's quickly look at the output of Trace[ ,TraceInternal->True] in Maxim's examples. I won't include the output here for it is very long but just comment on some obvious aspects. In the first example: Module[{subs = x -> x^2}, Plot[x /. subs, {x, 0, 1}, Compiled -> False]] The function to be plotted is first turned to x/x->x^2 which is not evaluated but numeric values of x are substituted in turn, thus giving things like: 4.16667 10^-8 /. 4.16667 10^-8 -> 1.73611 10^-15 and then the Plot is created. This has the same effect as using Evaluate, as I originally wrongly claimed, but this this is just an accident because when we change the example to Module[{subs = x -> x^(1/3)}, Plot[x^3 /. subs, {x, 0, 1}, Compiled -> False]] we see different behaviour. Now the substitutions take the form: 0.0000667603 /. 0.040567 -> 0.343604 which now of course also has no effect. In the case Module[{subs = x -> x^2}, Plot[x /. subs, {x, 0, 1}, Compiled -> True]] The values of x are computed but unlike in Compiled->False case not substituted into the rule subs. In other words the points to be plotted are 4.16667 10^-8 /. x ->x ^2 etc, which means that the rule has no effect and we get a straight line. But in the modified example Module[{subs = x -> x^(1/3)}, Plot[x^3 /. subs, {x, 0, 1}, Compiled -> True]] we see a different behaviour. CompiledFunction makes an appearance (although clearly compilation fails) and also the substitution rules fail to substitute but in a different way (similar to the Compiled->False setting). In the the case Module[{y := If[NumericQ[x], x, 1]}, Plot[x y, {x, 0, 1}, Compiled -> False]] analogously to the first case above, the test If[NumericQ[x], x, 1] is applied to numeric values in pointwise way, but, in the case Module[{y := If[NumericQ[x], x, 1]}, Plot[x y, {x, 0, 1}, Compiled -> True ]] the test is applied with symbolic x resulting in the answer 1. In both cases, when the Compiled->False is used, the "external" condition or definition is applied "pointwise". This behaviour is predictable and agrees with the documentation. In the case of Compile->True the explanation is essentially the one given by Bill Rowe, except that one should add that once compilation fails Mathematica proceeds to make a (wrong) plot, in a way which seems to depend on the character of the function that is being plotted and the external rules using to define it (you sometimes see CompiledFunciton in the output of Trace and sometimes don't). But as many people have already pointed out, when you are doing what you should not be doing, you can't complain that you are getting unpredictable results. Andrzej Kozlowski On 31 Dec 2003, at 17:23, Bill Rowe wrote: > On 12/30/03 at 4:14 AM, dontsendhere@. (Maxim) wrote: > >> I don't see any problem with Plot[Random[],{x,0,1},Compiled->True] >> either, it was just an >> illustration (if you don't like Random[], you can insert A Very >> Complicated Expression instead). But you have to read the thread from >> the beginning, the problem is >> with >> >> Module[{y := If[NumericQ[x], x, 1]}, >> Plot[x y, {x, 0, 1}, Compiled -> True] >> ] > > But this too works as should be expected from the documentation. In > order for the expression x y to be Compiled it must be evaluated and > this must happen before Plot assigns values to any portion of the > expression. Consequently, when it is evaluated x is not numeric so y > evaluates to 1 and the product evaluates to x. Hence, with > Compiled->True a line with slope = 1 results. > > OTOH, with Compiled->False, Plot supplies a numeric value to x then > evaluates the expression. Since x is now numeric, y evalutes to x and > the product evaluates to x^2. The resulting plot is a parabola. > > -- > To reply via email subtract one hundred and four > > > Andrzej Kozlowski Chiba, Japan http://www.mimuw.edu.pl/~akoz/