MathGroup Archive 2004

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

Search the Archive

Re: Compile

  • To: mathgroup at smc.vnet.net
  • Subject: [mg45511] Re: Compile
  • From: Maxim <dontsendhere@.>
  • Date: Sat, 10 Jan 2004 16:43:31 -0500 (EST)
  • References: <bto1j0$2ip$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com


"Simons, F.H." wrote:

> Maxim Retin produced two examples asking to explain why they behave as they do. As Hartmut Wolf already pointed out, the first example is completely predictable in the way discussed earlier. So let us turn to Maxim's second example:
>
> > -----Original Message-----
> > From: Wolf, Hartmut [mailto:Hartmut.Wolf at t-systems.com]
To: mathgroup at smc.vnet.net
> > Sent: woensdag 7 januari 2004 23:31
> > To: mathgroup at smc.vnet.net
> > Subject: [mg45511]  Re: Compile
> >
> ......
> > Your new example shows up other "interesting things" (to those who are
> > interested of course).
> >
> > In[27]:=
> > y := (Print[x]; x + If[NumericQ[x], 1, 0]);
> > Trace[Plot[y, {x, 0, 1}, Compiled -> True, AspectRatio -> Automatic,
> >       PlotPoints -> 3], x | y, TraceInternal -> True] // InputForm
> > >From In[27]:= x
> > >From In[27]:= x
> > >From In[27]:= 5.*^-7
> > >From In[27]:= 0.486804
> > >From In[27]:= 1.
>
> ..........
> > What is new, are obviously two (additional) evaluations of y
> > when x has no
> > value, before doing the plot. What comes to my phantasy is a
> > compilator in
> > desperate search of the variable x to become bound, detecting
> > it when an
> > exterior variable becomes evaluated, and now binding it (as
> > in contrary of
> > above) in a function call. (y however is not evaluated within
> > the compiled
> > expression.)
> >
> >
> Here my phantasy went into a different direction.
>
> To start with, let us simplify Maxim's example.
>
> y:= Sin[x]
> Plot[y, {x, 0, 3}]
>
> indeed produces a plot of the sine function, as expected(?!). But a further reflection shows that this is not obvious. The option Compiled is True, so Mathematica starts with compiling y as a function of x. The compiled result contains the symbol y. Then, since Compiled is set to True, the numerical values are substituted (not assigned) into the compiled function and therefore have no effect on the symbol y. This symbol now evaluates to Sin[x] which is not numerical and therefore the graph cannot be plotted. However, we do see the graph of the sine, so my explanation along the lin
es of my previous message seems to be incorrect. That is what Maxim's example suggests.
>
> To see what is going on, have a look at the following commands:
>
> Clear[y];
> fc = Compile[{{x, _Real}}, y];
>
> y:= (Print[x]; Sin[x]);
> fc[0.3]
>
> First the symbol x is printed, then an error message that the symbol Sin[x] is not numerical, then the message that the uncompiled code will be used, which results in another evaluation of y and therefore the printing of x, and the outcome Sin[x].
>
> Now let us look at the Plot command:
>
> y := (Print[x];Sin[x]);
> Plot[y, {x, 0, 3}]
>
> What happens? First Mathematica compiles y as a function of x. Then evaluations starts by substituting (not assigning) a numerical value of x in the compiled function. Then y is evaluated and x is printed, the evaluation of the compiled function fails so the uncompiled code will be used, resulting in another printing of x and a non-numerical value of the function AND NOW MATHEMATICA SIMPLY SWITCHES TO THE UNCOMPILED MODE and makes the plot as if the option Compiled was set to False. Therefore the result of the plot command is what was hoped that the result would be. Obviously this
 is not a rigid mathematical proof that is happening, but it explains what is going on, including Maxim's examples.
>
> Two of Maxim's examples now are particularly illustrative:
>
> y := If[NumericQ[x], 1, 0]
> Plot[y, {x,0,1}]
>
> Evaluation of the compiled argument results in 0, so the result is the horizontal axis.
>
> y := x+ If[NumericQ[x], 1, 0]
> Plot[y, {x,0,1}]
>
> Evaluation of the compiled argument results in x, which is not numerical. So the plotting switches to Compiled->False, and x+1 is plotted.
>
> Fred Simons
> Eindhoven University of Technology

If we use Trace, we can see that Mathematica evaluates a CompiledFunction for several values of x:

Trace[
  Module[
    {y := x + If[NumericQ[x], 1, 0]},
    Plot[y, {x, 0, 1}, Compiled -> True,
      PlotPoints -> 3, PlotDivision -> 1]
  ],
  TraceInternal -> True, TraceOff -> Show
]

So it cannot be equivalent to using Compiled->False. In fact, the situation is the opposite of what you describe: CompiledFunction appears in the second example (shown above), but not in the first one (with y := If[NumericQ[x], 1, 0]).

How does this CompiledFunction give a numeric result then? You forget that Plot works like Block, so effectively we have a CompiledFunction inside of a Block:

In[1]:=
Module[
  {y := x, cf},
  cf = Compile[{x}, y];
  Block[{x = 1},
    cf[2]
]]

Out[1]=
1.

The argument of CompiledFunction isn't plugged in anywhere, but x is evaluated in the context set up by Block. Actually this was already explained by Hartmut Wolf.

Besides, what is "evaluation of the compiled argument"? Without assigning any value to the iterator variable? Then, according to your theory, when Mathematica needs to execute Plot[x,{x,0,1}] it evaluates the expression to be plotted, which evaluates to x, which isn't numerical, so Mathematica switches to Compiled->False. Evidently, it doesn't work that way.

At the very least, please get my name right the next time...

Maxim Rytin
m.r at prontomail.com



  • Prev by Date: Re: Problem with FullSimplify in Version 5: Rationals are converted to Reals
  • Next by Date: Re: how to delete duplicate items in the same list
  • Previous by thread: RE: RE: Re: Compile
  • Next by thread: Re: Re: Compile