4
$\begingroup$

Let's consider this function

f[a_] := x^2 /. FindMinimum[-a x^2 + x^4, {x, 1}][[2]]

Why the output of the following two Plot are different:

Plot[f[y], {y, -3, 3}]
Plot[f[x], {x, -3, 3}]
$\endgroup$
  • 1
    $\begingroup$ In the second case, you are now evaluating x^2 /. FindMinimum[-x^3 + x^4, {x, 1}][[2]], no? Use Module[]: f[a_] := Module[{x}, x^2 /. FindMinimum[-a x^2 + x^4, {x, 1}][[2]]]. $\endgroup$ – J. M. is away May 18 '17 at 10:09
  • 1
    $\begingroup$ Yes I see; but I expected that in f[x] the argument x is a free variable; that means that I thought Plot doesn't evaluate f[x] before than substituting a value; so I thought Plot take the value -3 and print {-3, f[-3]} after -2.999 and print {-2.999, f[-2.999]} and so on. But it's not the case. On the other hand, Plot cannot evaluate f[y] before substituting a value for y, as it seems to do in f[x]: in this case it cannot evaluate f[y]. So how does Plot work?? $\endgroup$ – Giancarlo May 18 '17 at 10:47
  • $\begingroup$ Plot works like this: Block[{x = 3}, f[x]] // Trace -- Note that FindMinimum effectively blocks the instances of x in the definition, but not the parameter x in f[x] which has already evaluated to 3 nor the x in the x^2 outside of FindMinimum, which has also already evaluated to 3. $\endgroup$ – Michael E2 May 18 '17 at 22:20
3
$\begingroup$

According to the docs for Plot, it effectively uses Block to evaluate f[x] in a localized environment. Tracing the evaluation of f[x] inside a Block reveals what happens:

Block[{x = 3}, f[x]] // Trace

{Block[{x = 3}, f[x]],      (* begin evaluation *)
 {x = 3, 3},                (* evaluate first argument *)
 {                          (* begin evaluation of f[x] *)
  {x, 3},                   (*   first evaluate argument x *)
  f[3],                     (*   begin evaluation of f[3] *)
  x^2 /. FindMinimum[-3 x^2 + x^4, {x, 1}][[2]],  (* f[3] replaced by def. of f *)
  {                         (*     begin evaluation of ReplaceAll *)
   {x, 3}, 3^2, 9},         (*       evaluation of x^2 *)
  {                         (*       begin evaluation of FindMinimum *)
   {FindMinimum[-3 x^2 + x^4, {x, 1}],  
    {{{-3, -3}, -3 x^2}, -3 x^2 + x^4},     (* evaluate first argument *)
    {{x} =., {x =.}, {x =., Null}, {Null}}, (*   block x *)
    {-2.2499999999999996`, {x -> 1.2247448715336158`}}, (* FindMinimum result *)
    {                       (*         x has a value: begin evaluation Rule in result *)
     {{x, 3},               (*           first argument *)
      3 -> 1.2247448715336158`,  (*      Rule with value of x *)
      3 -> 1.2247448715336158`}, (*    result of Rule evaluation *)
     {3 -> 1.2247448715336158`}},
    {-2.2499999999999996`, {3 -> 1.2247448715336158`}} (* final result of FindMinimum *)
    },
   {-2.2499999999999996`, {3 -> 1.2247448715336158`}}[[2]], (* evaluate Part *)
   {3 -> 1.2247448715336158`}},  (*   final result of 2nd arg. of ReplaceAll *)
  9 /. {3 -> 1.2247448715336158`}, (* evaluate ReplaceAll with evaluated arguments *)
  9},                       (*     result of ReplaceAll *)
 9}                         (*   result of f[x] *)

If one follows closely, one can see that the result of Plot will be the graph of x^2, except when x and x^2 are identical, that is if x is zero or one. Well, it's really hard to get Plot to hit a particular number exactly. But it's easier with Table, which evaluates its argument in a way similar to Plot.

ListLinePlot[Table[{x, f[x]}, {x, -1./2^13, 1./2^13, 1./2^20}], 
 Frame -> True, Axes -> False]

Mathematica graphics

ListLinePlot[Table[{x, f[x]}, {x, 1 - 1./2^2, 1 + 1./2^2, 1./2^9}], 
 Frame -> True, Axes -> False]

Mathematica graphics

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.