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 have this code to produce an interactive visualization of a tangent plane to a function:

Clear[f]
f[x_, y_] := x^3 + 2*y^3
Manipulate[
 Show[
  Plot3D[f[x, y], {x, -1, 1}, {y, -1, 1}, PlotStyle -> Opacity[0.8]],
  Plot3D[f[point[[1]], point[[2]]] +
    Limit[(f[point[[1]] + h, point[[2]]] - f[point[[1]], point[[2]]])/
       h, h -> 0]*(x - point[[1]]) +
    Limit[(f[point[[1]], point[[2]] + h] - f[point[[1]], point[[2]]])/
       h, h -> 0]*(y - point[[2]]), {x, -1, 1}, {y, -1, 1}, 
   PlotStyle -> Opacity[0.8], MeshStyle -> Gray]],
 {{point, {0, 0}}, {-1, -1}, {1, 1}}, 
 SaveDefinitions -> True]

It is, however, extremely slow. I suspect that the reason is that I unnecessarily compute the partial derivatives over and over again inside the second Plot3D, so my question is: how to change it?

Note: I am using the above code also for other functions as discussed here, and that is the reason for the Limit in computation of partial derivatives.

share|improve this question
add comment

2 Answers 2

Simply move the derivative computation outside the scope of the Manipulate, using either D or Limit.

f[x_, y_] = x^3 + 2 y^3;
fx[x_, y_] = D[f[x, y], x];
fx[x_, y_] = Limit[(f[x + h, y] - f[x, y])/h, h -> 0];
fy[x_, y_] = D[f[x, y], y];
fy[x_, y_] = Limit[(f[x, y + h] - f[x, y])/h, h -> 0]
Manipulate[
 x0 = p[[1]]; y0 = p[[2]];
 Show[{
   Plot3D[{f[x, y], 
     f[x0, y0] + fx[x0, y0] (x - x0) + fy[x0, y0] (y - y0)},
    {x, -2, 2}, {y, -2, 2}, BoxRatios -> {1, 1, 1}, 
    PlotRange -> {{-2, 2}, {-2, 2}, {-25, 25}},
    PlotStyle -> {Directive[Opacity[0.6]], 
      Directive[Orange, Opacity[0.6]]},
    ViewPoint -> {2.5, -2, 1}, ClippingStyle -> None],
   Graphics3D[{PointSize[Large], 
     Point[{p[[1]], p[[2]], f[p[[1]], p[[2]]]}]}]
   }],
 {{p, {1, 1}}, {-1, -1}, {2, 2}}]
share|improve this answer
    
Interesting. Why do you provide two rules for fx[x_,y_]? –  mbork Sep 29 '12 at 19:36
1  
@mbork Either definition works, although the second clearly overwrites the first. I was simply trying to emphasize the fact that you can use either the built in D operator or the Limit definition, as you indicated that you might need to. –  Mark McClure Sep 29 '12 at 19:40
1  
OK, thanks. For the moment I thought that somehow the Limit one is chosen if the D doesn't work (e.g., when the function is given by a separate rule for one point). And thanks for the nicety - the large point! (I did it using a one-element list in ListPointPlot3D, definitely less elegant.) –  mbork Sep 29 '12 at 19:42
    
@mbork you could also show the Points using Epilog –  Simon Sep 30 '12 at 2:07
1  
@Simon Epilog is really for 2D graphics. From the documentation: "In three-dimensional graphics, two-dimensional graphics primitives can be specified by the Epilog option. The graphics primitives are rendered in a 0,1 coordinate system." - Hence, the Show[{Plot3D[__], Graphics3D[__]}] construct. –  Mark McClure Sep 30 '12 at 2:38
show 2 more comments

The limits can be calculated analytically one time and then used inside your Manipulate. You can use With to place the final expression where you need them:

f[x_, y_] := x^3 + 2*y^3;
With[{l1 = Limit[(f[px + h, py] - f[px, py])/h, h -> 0], 
  l2 = Limit[(f[px, py + h] - f[px, py])/h, h -> 0]},
 Manipulate[
  {px, py} = point;
  Show[Plot3D[f[x, y], {x, -1, 1}, {y, -1, 1}, 
    PlotStyle -> Opacity[0.8]], 
   Plot3D[f[point[[1]], point[[2]]] + l1*(x - point[[1]]) + 
     l2*(y - point[[2]]), {x, -1, 1}, {y, -1, 1}, 
    PlotStyle -> Opacity[0.8], 
    MeshStyle -> Gray]], {{point, {0, 0}}, {-1, -1}, {1, 1}}, 
  SaveDefinitions -> True]
 ]
share|improve this answer
    
Thanks! I just discovered With myself, too, but I've put it inside Show; I guess this doesn't make much difference. –  mbork Sep 29 '12 at 19:36
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.