# Why does LogLinearPlot sample its argument outside the specified domain?

I experience a weird bug in the function LogLinearPlot. If the input is an interpolation function, such as the one created like this,

int = NDSolve[{x'[t] == 1, x[0] == 0}, x, {t, 0, 100}]


then when plotting it I get an error message (but the plot works fine)

LogLinearPlot[x[t] /. int, {t, 0.1, 100}]

InterpolatingFunction::dmval: "Input value {-2.30244} lies outside the range of data in the interpolating function. Extrapolation will be used"


You will not be surprised to know that log(0.1)=-2.302. It seems that LogLinearPlot tries to plug in the wrong values in the function, but the plot does look good.

Update: This is working correctly in version 9.

-
Reap@LogLinearPlot[Sow[x], {x, 2, 10}] will show that this evaluation happens only once. EvaluationMonitor does not reveal this evaluation. The value is not precisely the logartihm of the lower bound, it is slightly larger than that and also depends on the upper bound. –  Szabolcs May 24 '12 at 8:52
–  Szabolcs May 24 '12 at 8:56
And yet again, it turns out that I have already asked the very same question on MathGroup, 3 years ago, and I have completely forgotten about it: groups.google.com/d/topic/comp.soft-sys.math.mathematica/… –  Szabolcs May 24 '12 at 8:58
@Szabolcs Since this seems to be fixed in v9, I've added the tag version-8. What is the policy in such situations? I don't even know whether it was introduced in v8, v7 or v6. –  István Zachar Apr 9 '13 at 23:13
@István Here's the meta on that. –  Szabolcs Apr 10 '13 at 0:21

This is fixed in version 9.

This came up on MathGroup before. Since it hasn't been fixed for so long, I wasn't sure if it was really a bug, so I did some spelunking (and some speculation) today to find out what's happening. To jump to the end: I think it's a bug.

First, let's see what arguments does LogLinearPlot really pass to the function:

Reap@LogLinearPlot[Sow[x], {x, 1, 10}]

(* ==>
{x, 0.0000470385, 1., 1.04623, 1.09877, 1.15021, ... }
*)


Indeed, it does sample outside the domain (0.000047). If you try the EvaluationMonitor option, you'll see that this strange value won't show up there.

Now let's try a plain Plot:

Reap@Plot[Sow[x], {x, 1, 2}]

(* ==>
{1.00002, x, 1., 1.01963, 1.04091, 1.06078, ... }
*)


Notice a strange value at the beginning again, 1.00002. It seems that Plot[f[x], {x, min, max}] always starts by evaluating the function with a numerical value that is midway between min and max, approximately (but not always exactly) at min + 0.00002 (max-min). After this, Plot will evaluate the argument symbolically.

My guess is that Plot does this to discover some information about the function, and also to decide whether the evaluate it or not. Plot is HoldAll, and we know that often it is necessary to use Plot[f[x] // Evaluate, ...]. In my experience, Plot actually tries to be smart and decide whether it should do this automatically. It also has an undocumented Evaluated option with the default value being Automatic, which I believe controls this behaviour. You can set it to True or False and see what happens.

Now let's see what LogLogPlot does. A little spelunking reveals that it calls the functions scaledPlot2 and scaledPlot (in the GraphicsLogPlotDump context), which then call Plot with the following Method options (simplified):

Reap@Plot[
Sow[x], {x, Log[1], Log[10]},
{Method -> {"MappingFunctions" -> {{#1, #2} &, {#1, #2} &},
"DomainMappingFunctions" -> {Exp[#1] &}}}]


Note that the bounds have been transformed using Log (in scaledPlot2), and the "MappingFunctions" and "DomainMappingFunctions" options tell Plot about this transformation.

It'll evaluate the function with these arguments:

{0.0000470385, x, 1., 1.04623, 1.09877, 1.15021, ... }


Note that even though the bounds are given as Log[1] and Log[10], Plot will transform these values before passing it to its argument function for all value except the first two special ones.

My conclusion: Plot fails to transform x using the "DomainMappingFunction" when passing the function the first two "discovery values". I'd call this a bug.

It's not a serious bug though unless your function does something really bad and unexpected when called with wrong arguments (hang, crash, format your hard drive).

-
I'm not sure why I did this, after all it won't help anyone ... but there's no other answer in this case than "it's a bug". –  Szabolcs May 24 '12 at 10:15
It just helped me. "Plot actually tries to be smart and decide whether it should do this automatically.". It reassured me why something I had tried in another question didn't work. I assumed Plot just never evaluated, and the results proved me wrong –  Rojo May 24 '12 at 10:18
@Rojo I am not sure how Plot decides whether to evaluate or not (IIRC my experiments with the Evaluated option gave inconsistent results), but I'm sure that sometimes it does and sometimes it doesn't: there's some heuristic at work. –  Szabolcs May 24 '12 at 10:23
Thanks. I had to fool those heuristics by wrapping it in a function that did nothing useful. Fortunately there's EvaluationMonitor (and Heike to remind me of it) –  Rojo May 24 '12 at 10:26
+1 mainly because "... format your hard drive" is food for thought –  belisarius May 24 '12 at 11:39