Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am new to Mathematica and was experimenting with a simply problem of plotting a tangent to a curve and being able to move the point at which the tangent is drawn using Manipulate. When I run the following, the cell flickers a lot and it also seems to consume a lot of CPU? Is there a way to avoid this?

Manipulate[
  Module[{f, x, y, dx, dy},
    dx = dy = 1;
    f[x_] := x^2;
    tangent[x_, y_] := {{x - dx, y - f'[x] dy}, {x + dx, y + f'[x] dy}};
    g = Graphics[Line @ tangent[x0, f[x0]], PlotRange -> {{-5, 5}, {-5, 5}}];
    p = Plot[f[x], {x, -5, 5}];
    Show[p, g]],
  {{x0, 2}, -4, 4}]
share|improve this question
1  
You might want to look at this –  m_goldberg Feb 17 '13 at 17:09
    
Thanks but doesn't explain why the above doesn't work ? In my example it should just evaluate the function f[x] & tangent[] when i move the slider but clearly its doing something different. –  David McHarg Feb 17 '13 at 17:15
1  
The link shows one correct approach to doing what you want and answers your question "how to avoid this?" If your question is really: how do I debug this? -- well, this isn't a debugging service. I will say this -- defining a Module inside a Manipulate is not a good idea, nor is evaluating the derivative of a simple function over and over. –  m_goldberg Feb 17 '13 at 17:23
    
Thanks. But why is evaluating a function inside a manipulate a bad idea ? –  David McHarg Feb 17 '13 at 17:29
    
Nothing wrong with evaluating a function in a Manipulate, but taking the derivative of x^2 many times when it could done once is not good. –  m_goldberg Feb 17 '13 at 17:33
show 2 more comments

4 Answers 4

I hope you'll forgive my changing one thing that's been bugging me about the code: If $y=f(x)$, then $dy = f'(x)\; dx$, not $f'(x)\; dy$. (The original code works because dy is set equal to dx.)

tangent[x_, dx_, f_] := {{x - dx, f[x] - f'[x] dx}, {x + dx, f[x] + f'[x] dx}};
f[x_] := x^2;
Manipulate[With[{dx = 1},
  p = Plot[f[x], {x, -5, 5}, Epilog -> Dynamic@Line@tangent[x0, dx, f]]],
 {{x0, 2}, -4, 4}, SaveDefinitions -> True]

I also wrapped the tangent line in Dynamic. The tangent line is the only thing that changes, and adding Dynamic makes it the only thing recalculated when x0 changes. The plot of f[x] is not recalculated, which lowers CPU usage even more. That savings is unimportant in this example, but the principle illustrated is useful.

share|improve this answer
    
Thanks. Wasn't aware of Dynamic so useful. Thanks for spotting the typo in dy. –  David McHarg Feb 17 '13 at 19:41
add comment

Solved the problem by changing things around a little. This resolves the flickering and CPU usage.

Module[{f,x,y,dx,dy},
dx=dy=1;
f[x_]:=x^2;
tangent[x_,y_]:={{x-dx,y-f'[x] dy},{x+dx,y+f'[x] dy}};
p=Plot[f[x],{x,-5,5}];
tangent[x_]:=Graphics[Line@tangent[x,f[x]],PlotRange->{{-5,5},{-5,5}}];
Manipulate[Show[p,tangent[x0]],{{x0,2},-4,4}]
]

Regards David.

share|improve this answer
    
+1 for your own initiative. –  Yves Klett Feb 17 '13 at 17:51
add comment

Well, while your (David McHarg's) current solution is much better, sometimes one can not avoid some heavy recalculation inside Manipulate. For such cases TrackedSymbols is indispensable. This tells manipulate which symbols to monitor for change. So this works as expected:

Manipulate[DynamicModule[{f, x, y, dx, dy}, dx = dy = 1;
  f[x_] := x^2;
  tangent[x_, y_] := {{x - dx, y - f'[x] dy}, {x + dx, y + f'[x] dy}};
  g = Graphics[Line@tangent[x0, f[x0]], 
    PlotRange -> {{-5, 5}, {-5, 5}}];
  p = Plot[f[x], {x, -5, 5}];
  Show[p, g]], {{x0, 2}, -4, 4}, TrackedSymbols :> {x0}]
share|improve this answer
    
Thanks. Exactly what i was looking for. Always good to understand different approaches. –  David McHarg Feb 17 '13 at 17:52
add comment

TrackedSymbols is not needed if one just localizes all variables in Modules (which is what one should do in the first place). Many like to use global variables all over the place and this causes such problems.

Manipulate[

 Module[{x, y, dx, dy, g, p},

  dx = dy = 1;
  g = Graphics[Line@tangent[x, x0, dx, dy, f],PlotRange -> {{-5, 5}, {-5, 5}}];
  p = Plot[f[x], {x, -5, 5}];
  Show[p, g]
 ],

 {{x0, 2}, -4, 4},

 Initialization :>
  {
   tangent[var_Symbol, x0_, dx_, dy_, f_]:= Module[{der = D[f, var] /. var -> x0},
     {{x0 - dx, f[x0] - der dy}, {x0 + dx, f[x0] + der dy}}
   ];

   f[x_] := x^2;
   }
 ]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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