Visualizing Directional Derivatives and Gradients \302\251Mike May, S.J., Saint Louis University, 2006- maymk@slu.edu As we have been looking at directional derivatives and gradients, it seems worthwhile to look at a Maple visualization of everything we have been doing. First we want to load the appropriate commands. We will need commands from the package plots. (Restart cleans up in case we were already running a Maple worksheet.) restart: with(plots):
<Text-field style="Heading 1" layout="Heading 1">Directional derivatives:</Text-field> For preliminaries we want to define the function, the point in the x-y plane we are evaluating at and the direction vector we are interested in taking a derivative in. f := (x,y) -> x^2 + 2*y^2; xval :=2: yval:= 3: dirvec := <3, 4>; Next we would like to compute a unit vector in the desired direction and the z-coordinate of the point of interest. uvec := dirvec/sqrt(dirvec.dirvec); zval := f(xval, yval); To visualize what we are doing, we look at the surface together with a plane containing the direction vector. surf:= plot3d(f(x,y), x=xval-2..xval+2, y=yval-2..yval+2, axes=boxed, color=red, style = patchnogrid): pathc :=spacecurve( [xval+t*uvec[1], yval+t*uvec[2], f(xval+t*uvec[1], yval+t*uvec[2])], t=-2..2, color=blue, thickness=2): cutplane := plot3d([xval+u*uvec[1], yval+u*uvec[2],zval+v], u=-2..2,v=-5..5, color=yellow, style=patchnogrid): display3d({cutplane, surf, pathc}); The surface is in red, the plane that cuts the cross section in the desired direction is in yellow, and the curve in the cross section is in blue. We can get a better view if we look at the function as a function of one variable in the cutting plane. plot(f(xval+t*uvec[1],yval+t*uvec[2]), t=-2..2); We can compute the directional derivative from the definition. dderiv := limit((f(xval+t*uvec[1], yval+t*uvec[2]) - f(xval, yval))/t, t=0); This can be used to plot a tangent line to the curve. plot({f(xval+t*uvec[1],yval+t*uvec[2]), zval+dderiv*t}, t=-2..2); We can also put this line back on the 3D graph of the surface. tanline :=spacecurve([xval+t*uvec[1], yval+t*uvec[2], zval+t*dderiv], t=-2..2, color=green, thickness=3): display3d({cutplane, surf, pathc, tanline}); For convenience sake we can put everything together into one block of code. f := (x,y) -> x^2 + 2*y^2; xval :=2: yval:= 3: dirvec := <3, 4>: uvec := dirvec/sqrt(dirvec.dirvec); zval := f(xval,yval); dderiv := limit((f(xval+t*uvec[1], yval+t*uvec[2]) - f(xval, yval))/t, t=0); plot([f(xval+t*uvec[1],yval+t*uvec[2]), zval+dderiv*t],t=-2..2, legend=["f restricted to u", "directional derivative"]); surf:= plot3d(f(x,y), x=xval-2..xval+2, y=yval-2..yval+2, axes=boxed, color=red, style = patchnogrid): pathc := spacecurve( [xval+t*uvec[1], yval+t*uvec[2], f(xval+t*uvec[1], yval+t*uvec[2])], t=-2..2, color=blue, thickness=2): cutplane := plot3d([xval+u*uvec[1], yval+u*uvec[2],zval+v], u=-2..2,v=-5..5, color=yellow, style=patchnogrid): tanline :=spacecurve([xval+t*uvec[1], yval+t*uvec[2], zval+t*dderiv], t=-2..2, color=green, thickness=3): display3d({cutplane, surf, pathc, tanline});
<Text-field style="Heading 1" layout="Heading 1">Exercise:</Text-field> 1) Let LUklbXJvd0c2Iy9JK21vZHVsZW5hbWVHNiJJLFR5cGVzZXR0aW5nR0koX3N5c2xpYkdGJzYlLUkjbWlHRiQ2I1EhRictRiM2J0YrLUYjNiUtRiw2JVEiZ0YnLyUnaXRhbGljR1EldHJ1ZUYnLyUsbWF0aHZhcmlhbnRHUSdpdGFsaWNGJy1JI21vR0YkNi1RMCZBcHBseUZ1bmN0aW9uO0YnL0Y6USdub3JtYWxGJy8lJmZlbmNlR1EmZmFsc2VGJy8lKnNlcGFyYXRvckdGRC8lKXN0cmV0Y2h5R0ZELyUqc3ltbWV0cmljR0ZELyUobGFyZ2VvcEdGRC8lLm1vdmFibGVsaW1pdHNHRkQvJSdhY2NlbnRHRkQvJSdsc3BhY2VHUSYwLjBlbUYnLyUncnNwYWNlR0ZTLUkobWZlbmNlZEdGJDYkLUYjNiUtRiw2JVEieEYnRjZGOS1GPTYtUSIsRidGQEZCL0ZGRjhGR0ZJRktGTUZPRlEvRlVRLDAuMzMzMzMzM2VtRictRiw2JVEieUYnRjZGOUZALUY9Ni1RIj1GJ0ZARkJGRUZHRklGS0ZNRk8vRlJRLDAuMjc3Nzc3OGVtRicvRlVGZW8tRiM2JS1GLDYlUSRzaW5GJy9GN0ZERkBGPC1GVzYkLUYjNiVGKy1GIzYnRistRiM2Iy1JJW1zdXBHRiQ2JUZlbi1JI21uR0YkNiRRIjJGJ0ZALyUxc3VwZXJzY3JpcHRzaGlmdEdRIjBGJy1GPTYtUSIrRidGQEZCRkVGR0ZJRktGTUZPL0ZSUSwwLjIyMjIyMjJlbUYnL0ZVRmNxLUYjNiMtRmZwNiVGXm9GaHBGXHFGK0YrRkBGK0Yr. Modify the code above to plot the graph of g(x,y) in a region around the point (3, 4) together with a line tangent in the direction (5, 12).
<Text-field style="Heading 1" layout="Heading 1">Gradients:</Text-field> The gradient of a function can be thought of in a number of ways. The easiest description is symbolic. The gradient of f(x,y) is defined to be the vector with components equal to the partial derivatives. In the terminology we have been using, grad(f) = [x-slope, y-slope]. Notice that the gradient has as many components as the input vector, rather than the number of coordinates of a point on the graph. f := (x,y) -> x^2 + 2*y^2; xval :=2: yval:= 3: fx := diff(f(x,y),x); xslope := eval(fx, {x=xval, y=yval}); fy := diff(f(x,y), y); yslope := eval(fy, {x=xval, y=yval}); gradient := <xslope,yslope>; We are also told that the gradient should have direction that is perpendicular to the contour of the graph at that point. To see this put the contourplot and the gradient on the same graph. cplot := contourplot(f(x,y),x=xval-2..xval+2, y=yval-2..yval+2): gradv := plot([xval+t*xslope, yval+t*yslope,t=0..1], thickness=3, color=green): display({cplot, gradv},scaling=constrained); This relationship can be seen more clearly with the Maple command gradplot that plots a field of scaled gradient vectors. gplot := gradplot(f(x,y),x=xval-2..xval+2, y=yval-2..yval+2): cplot := contourplot(f(x,y),x=xval-2..xval+2, y=yval-2..yval+2): display({cplot, gplot}, scaling=constrained); Tied into the idea that the gradient is perpendicular to the contours is that it is the direction of steepest ascent. This means that we can visually check to see if we have computed the gradient correctly. If we take the cross section in the direction of the gradient it should be the direction that the function is rising most steeply. f := (x,y) -> x^2 + 2*y^2; xval :=2: yval:= 3: zval := f(xval,yval): fx := diff(f(x,y),x): mx := eval(fx, {x=xval, y=yval}): fy := diff(f(x,y), y): my := eval(fy, {x=xval, y=yval}): gradvec := <mx, my>; unitgradient := gradvec/sqrt(gradvec.gradvec); gradientderiv := mx*unitgradient[1]+my*unitgradient[2]; surf:= plot3d(f(x,y), x=xval-2..xval+2, y=yval-2..yval+2, axes=boxed, color=red, style = patchcontour): gradientpath :=spacecurve([xval+t*unitgradient[1], yval+t*unitgradient[2], f(xval+t*unitgradient[1], yval+t*unitgradient[2])], t=-2..2, color=blue, thickness=2): cutplane := plot3d([xval+u*unitgradient[1], yval+u*unitgradient[2],zval+v], u=-2..2,v=-5..5, color=yellow, style=patchnogrid): gradline :=spacecurve( [xval+t*unitgradient[1], yval+t*unitgradient[2], zval+t*gradientderiv], t=0..1, color=green, thickness=3): display3d({cutplane, surf, gradientpath, gradline});
<Text-field style="Heading 1" layout="Heading 1">Exercise:</Text-field> 2a) Let LUklbXJvd0c2Iy9JK21vZHVsZW5hbWVHNiJJLFR5cGVzZXR0aW5nR0koX3N5c2xpYkdGJzYlLUkjbWlHRiQ2I1EhRictRiM2J0YrLUYjNiUtRiw2JVEiZ0YnLyUnaXRhbGljR1EldHJ1ZUYnLyUsbWF0aHZhcmlhbnRHUSdpdGFsaWNGJy1JI21vR0YkNi1RMCZBcHBseUZ1bmN0aW9uO0YnL0Y6USdub3JtYWxGJy8lJmZlbmNlR1EmZmFsc2VGJy8lKnNlcGFyYXRvckdGRC8lKXN0cmV0Y2h5R0ZELyUqc3ltbWV0cmljR0ZELyUobGFyZ2VvcEdGRC8lLm1vdmFibGVsaW1pdHNHRkQvJSdhY2NlbnRHRkQvJSdsc3BhY2VHUSYwLjBlbUYnLyUncnNwYWNlR0ZTLUkobWZlbmNlZEdGJDYkLUYjNiUtRiw2JVEieEYnRjZGOS1GPTYtUSIsRidGQEZCL0ZGRjhGR0ZJRktGTUZPRlEvRlVRLDAuMzMzMzMzM2VtRictRiw2JVEieUYnRjZGOUZALUY9Ni1RIj1GJ0ZARkJGRUZHRklGS0ZNRk8vRlJRLDAuMjc3Nzc3OGVtRicvRlVGZW8tRiM2K0YrLUYjNiMtSSVtc3VwR0YkNiVGZW4tSSNtbkdGJDYkUSIyRidGQC8lMXN1cGVyc2NyaXB0c2hpZnRHUSIwRictRj02LVEiK0YnRkBGQkZFRkdGSUZLRk1GTy9GUlEsMC4yMjIyMjIyZW1GJy9GVUZpcC1GIzYlRl5wLUY9Ni1RMSZJbnZpc2libGVUaW1lcztGJ0ZARkJGRUZHRklGS0ZNRk9GUUZURmVuRmVwLUYjNiYtRl9wNiRRIjNGJ0ZARl1xLUYjNiMtRlxwNiVGXm9GXnBGYnBGKy1GPTYtUSgmbWludXM7RidGQEZCRkVGR0ZJRktGTUZPRmhwRmpwLUYjNiUtRl9wNiRRIjRGJ0ZARl1xRl5vRitGK0Yr. Estimate the gradient of g(x,y) at (3, 4) by plotting a contourplot and finding the direction perpendicular to the contours. 2b) Estimate the gradient of g(x,y) at (3, 4) by plotting the surface for a region around (3,4) and estimating the direction of steepest increase. 2c) Calculate the gradient of g(x,y) at (3, 4) symbolically.
<Text-field style="Heading 1" layout="Heading 1">A second look at directional derivatives</Text-field> The alternate way to produce the directional derivative is to use the gradient, computing the partial derivatives, evaluate them at our point, and then take the sum of the partials times the appropriate component of the unit direction vector. f := (x,y) -> x^2 + 2*y^2: xval :=2: yval:= 3: dirvec := <3, 4>: uvec := dirvec/sqrt(dirvec.dirvec); fx := diff(f(x,y),x); xslope := eval(fx, {x=xval, y=yval}); fy := diff(f(x,y), y); yslope := eval(fy, {x=xval, y=yval}); dirderiv := xslope*uvec[1]+yslope*uvec[2]; Notice that we do get the same answer for the directional derivative that we got with the formal definition above. This second method is more roundabout, but it has the advantage of being easier to do when we don't have Maple handy. In the second method we only have to take limits for two cross sections. JSFH
<Text-field style="Heading 1" layout="Heading 1">Exercise:</Text-field> 3) Let LUklbXJvd0c2Iy9JK21vZHVsZW5hbWVHNiJJLFR5cGVzZXR0aW5nR0koX3N5c2xpYkdGJzYlLUkjbWlHRiQ2I1EhRictRiM2J0YrLUYjNiUtRiw2JVEiZ0YnLyUnaXRhbGljR1EldHJ1ZUYnLyUsbWF0aHZhcmlhbnRHUSdpdGFsaWNGJy1JI21vR0YkNi1RMCZBcHBseUZ1bmN0aW9uO0YnL0Y6USdub3JtYWxGJy8lJmZlbmNlR1EmZmFsc2VGJy8lKnNlcGFyYXRvckdGRC8lKXN0cmV0Y2h5R0ZELyUqc3ltbWV0cmljR0ZELyUobGFyZ2VvcEdGRC8lLm1vdmFibGVsaW1pdHNHRkQvJSdhY2NlbnRHRkQvJSdsc3BhY2VHUSYwLjBlbUYnLyUncnNwYWNlR0ZTLUkobWZlbmNlZEdGJDYkLUYjNiUtRiw2JVEieEYnRjZGOS1GPTYtUSIsRidGQEZCL0ZGRjhGR0ZJRktGTUZPRlEvRlVRLDAuMzMzMzMzM2VtRictRiw2JVEieUYnRjZGOUZALUY9Ni1RIj1GJ0ZARkJGRUZHRklGS0ZNRk8vRlJRLDAuMjc3Nzc3OGVtRicvRlVGZW8tRiM2JS1GLDYlUSRzaW5GJy9GN0ZERkBGPC1GVzYkLUYjNiVGKy1GIzYnRistRiM2Iy1JJW1zdXBHRiQ2JUZlbi1JI21uR0YkNiRRIjJGJ0ZALyUxc3VwZXJzY3JpcHRzaGlmdEdRIjBGJy1GPTYtUSIrRidGQEZCRkVGR0ZJRktGTUZPL0ZSUSwwLjIyMjIyMjJlbUYnL0ZVRmNxLUYjNiMtRmZwNiVGXm9GaHBGXHFGK0YrRkBGK0Yr. Find the directional derivative of g(x,y) at the point (3, 4) in the direction (5, 12) by the method that uses the partials at the point.
<Text-field style="Heading 1" layout="Heading 1">Comparing the two methods of finding directional derivatives</Text-field> It is worthwhile verifying that the two methods of computing directional derivative give the same answer for any direction. (To be more precise, that these two methods with produce the same answer in every direction is the definition of the function being differentiable at a point.) We recall computations made above to get the x-slope and y-slope at a point. f := (x,y) -> x^2 + 2*y^2: xval :=2: yval:= 3: dirvec := <3, 4>: zval := f(xval,yval); xslope := eval(diff(f(x,y), x), {x=xval, y=yval}); yslope := eval(diff(f(x,y), y), {x=xval, y=yval}); We recall that a unit vector in direction theta has coordinates (cos(theta), sin(theta)). We then find a directional derivative in direction theta by using the definition of directional derivative. ddera := (f,theta) -> limit((f(xval+t*cos(theta), yval+t*sin(theta))-f(xval, yval))/t, t=0); We now compute the directional derivative by the method that uses x-slope and y-slope. dderb := theta -> cos(theta)*xslope + sin(theta)*yslope; It is now a simple matter to graphically compare the values obtained by the two methods for all angles theta. plot({ddera(f,theta)- dderb(theta)}, theta=0..2*Pi, axes=boxed); If we plot the ring of points (a+cos(theta), b+sin(theta), f(a,b)+ddera(theta)) we get a ring in the tangent plane (rotate the plot to see the underside of the tangent plane). surf:= plot3d(f(x,y), x=xval-2..xval+2, y=yval-2..yval+2, axes=boxed, color=red, style = patchnogrid): tanplane:= plot3d(zval+xslope*(x-xval)+yslope*(y-yval), x=xval-2..xval+2, y=yval-2..yval+2, axes=boxed, color=yellow, style = patchnogrid): tanring :=spacecurve([xval+cos(theta), yval+sin(theta), f(xval,yval)+ddera(f,theta)], theta=0..2*Pi, color=blue, thickness=2): display3d({surf, tanplane, tanring});
<Text-field style="Heading 1" layout="Heading 1">Exercise:</Text-field> 4) Let LUklbXJvd0c2Iy9JK21vZHVsZW5hbWVHNiJJLFR5cGVzZXR0aW5nR0koX3N5c2xpYkdGJzYlLUkjbWlHRiQ2I1EhRictRiM2J0YrLUYjNiUtRiw2JVEiZ0YnLyUnaXRhbGljR1EldHJ1ZUYnLyUsbWF0aHZhcmlhbnRHUSdpdGFsaWNGJy1JI21vR0YkNi1RMCZBcHBseUZ1bmN0aW9uO0YnL0Y6USdub3JtYWxGJy8lJmZlbmNlR1EmZmFsc2VGJy8lKnNlcGFyYXRvckdGRC8lKXN0cmV0Y2h5R0ZELyUqc3ltbWV0cmljR0ZELyUobGFyZ2VvcEdGRC8lLm1vdmFibGVsaW1pdHNHRkQvJSdhY2NlbnRHRkQvJSdsc3BhY2VHUSYwLjBlbUYnLyUncnNwYWNlR0ZTLUkobWZlbmNlZEdGJDYkLUYjNiUtRiw2JVEieEYnRjZGOS1GPTYtUSIsRidGQEZCL0ZGRjhGR0ZJRktGTUZPRlEvRlVRLDAuMzMzMzMzM2VtRictRiw2JVEieUYnRjZGOUZALUY9Ni1RIj1GJ0ZARkJGRUZHRklGS0ZNRk8vRlJRLDAuMjc3Nzc3OGVtRicvRlVGZW8tRiM2JS1GLDYlUSRzaW5GJy9GN0ZERkBGPC1GVzYkLUYjNiVGKy1GIzYnRistRiM2Iy1JJW1zdXBHRiQ2JUZlbi1JI21uR0YkNiRRIjJGJ0ZALyUxc3VwZXJzY3JpcHRzaGlmdEdRIjBGJy1GPTYtUSIrRidGQEZCRkVGR0ZJRktGTUZPL0ZSUSwwLjIyMjIyMjJlbUYnL0ZVRmNxLUYjNiMtRmZwNiVGXm9GaHBGXHFGK0YrRkBGK0Yr. Show that g(x,y) is differentiable at (3, 4) by showing that the 2 methods of computing directional derivatives give the same answer in all directions.
<Text-field style="Heading 1" layout="Heading 1">An example where the methods disagree</Text-field> The problem with looking at nice examples where everything works is it makes one wonder why anyone came up with the definition of directional derivatives in the first place when the gradient method is so much easier. It is thus worth looking at a case when the partials all work, but the function is not differentiable. The function we want to work with is LUklbXJvd0c2Iy9JK21vZHVsZW5hbWVHNiJJLFR5cGVzZXR0aW5nR0koX3N5c2xpYkdGJzYoLUkjbWlHRiQ2JVErcmNvczV0aGV0YUYnLyUnaXRhbGljR1EldHJ1ZUYnLyUsbWF0aHZhcmlhbnRHUSdpdGFsaWNGJy1JKG1mZW5jZWRHRiQ2JC1GIzYoLUYsNiNRIUYnLUYsNiVRInhGJ0YvRjItSSNtb0dGJDYtUSIsRicvRjNRJ25vcm1hbEYnLyUmZmVuY2VHUSZ1bnNldEYnLyUqc2VwYXJhdG9yR0YxLyUpc3RyZXRjaHlHRkgvJSpzeW1tZXRyaWNHRkgvJShsYXJnZW9wR0ZILyUubW92YWJsZWxpbWl0c0dGSC8lJ2FjY2VudEdGSC8lJ2xzcGFjZUdRJjAuMGVtRicvJSdyc3BhY2VHUSwwLjMzMzMzMzNlbUYnLUYsNiVRInlGJ0YvRjJGOkZERkQtRkE2LVEiPUYnRkQvRkdRJmZhbHNlRicvRkpGXG8vRkxGXG8vRk5GXG8vRlBGXG8vRlJGXG8vRlRGXG8vRlZRLDAuMjc3Nzc3OGVtRicvRllGZG8tRiM2J0Y6LUY2NiYtSSdtdGFibGVHRiQ2Ni1JJG10ckdGJDYnLUkkbXRkR0YkNigtRiM2JkY6LUkmbWZyYWNHRiQ2KC1GIzYmRjotRjY2JC1GIzYyRjotSSVtc3VwR0YkNiVGPS1JI21uR0YkNiRRIjVGJ0ZELyUxc3VwZXJzY3JpcHRzaGlmdEdRIjBGJy1GQTYtUSgmbWludXM7RidGREZbb0Zdb0Zeb0Zfb0Zgb0Zhb0Ziby9GVlEsMC4yMjIyMjIyZW1GJy9GWUZcci1GYnE2JFEjMTBGJ0ZELUZBNi1RJyZzZG90O0YnRkRGW29GXW9GXm9GX29GYG9GYW9GYm9GW3JGXXItRl9xNiVGPS1GYnE2JFEiM0YnRkRGZXFGYXItRl9xNiVGZW4tRmJxNiRRIjJGJ0ZERmVxLUZBNi1RJyZwbHVzO0YnRkRGW29GXW9GXm9GX29GYG9GYW9GYm9GW3JGXXJGYXFGYXJGPUZhci1GX3E2JUZlbi1GYnE2JFEiNEYnRkRGZXFGOkZERkRGOkZELUYjNiZGOi1GX3E2JS1GNjYkLUYjNihGOi1GX3E2JUY9RltzRmVxRl5zRmlyRjpGREZERltzRmVxRjpGRC8lLmxpbmV0aGlja25lc3NHUSIxRicvJStkZW5vbWFsaWduR1EnY2VudGVyRicvJSludW1hbGlnbkdGZXQvJSliZXZlbGxlZEdGXG9GOkZELyUpcm93YWxpZ25HRjwvJSxjb2x1bW5hbGlnbkdGPC8lK2dyb3VwYWxpZ25HRjwvJShyb3dzcGFuR0ZidC8lK2NvbHVtbnNwYW5HRmJ0LUZhcDYoLUYjNilGOi1GNjYkLUYjNiZGPS1GQTYtRkNGREZbb0ZJRl5vRl9vRmBvRmFvRmJvRlVGWEZlbkZERkRGOi1GQTYtUSUmbmU7RidGREZbb0Zdb0Zeb0Zfb0Zgb0Zhb0Zib0Zjb0Zlby1GNjYkLUYjNiYtRmJxNiRRIjBGJ0ZERlx2RmV2RkRGREY6RkRGanRGXHVGXnVGYHVGYnVGanRGXHVGXnUtRl5wNictRmFwNigtRiM2JkY6RmV2RjpGREZqdEZcdUZedUZgdUZidS1GYXA2KC1GIzYoRjpGaHVGaG5GYXZGOkZERmp0Rlx1Rl51RmB1RmJ1Rmp0Rlx1Rl51LyUmYWxpZ25HUSVheGlzRicvRlt1USliYXNlbGluZUYnL0ZddUZldC9GX3VRJ3xmcmxlZnR8aHJGJy8lL2FsaWdubWVudHNjb3BlR0YxLyUsY29sdW1ud2lkdGhHUSVhdXRvRicvJSZ3aWR0aEdGXngvJStyb3dzcGFjaW5nR1EmMS4wZXhGJy8lLmNvbHVtbnNwYWNpbmdHUSYwLjhlbUYnLyUpcm93bGluZXNHUSVub25lRicvJSxjb2x1bW5saW5lc0dGaXgvJSZmcmFtZUdGaXgvJS1mcmFtZXNwYWNpbmdHUSwwLjRlbX4wLjVleEYnLyUqZXF1YWxyb3dzR0Zcby8lLWVxdWFsY29sdW1uc0dGXG8vJS1kaXNwbGF5c3R5bGVHRlxvLyUlc2lkZUdRJnJpZ2h0RicvJTBtaW5sYWJlbHNwYWNpbmdHRmZ4RkQvJSVvcGVuR1EifGZyRicvJSZjbG9zZUdGPC1GQTYtUTEmSW52aXNpYmxlVGltZXM7RidGREZbb0Zdb0Zeb0Zfb0Zgb0Zhb0Zib0ZVL0ZZRlctRkE2LVEiLkYnRkRGW29GXW9GXm9GX29GYG9GYW9GYm9GVUZkekZERjpGRA== This looks like quite a strange function, but it looks a lot nicer in polar coordinates. Then we have LUklbXJvd0c2Iy9JK21vZHVsZW5hbWVHNiJJLFR5cGVzZXR0aW5nR0koX3N5c2xpYkdGJzYsLUkjbWlHRiQ2I1EhRictRiw2JVErcmNvczV0aGV0YUYnLyUnaXRhbGljR1EldHJ1ZUYnLyUsbWF0aHZhcmlhbnRHUSdpdGFsaWNGJy1JI21vR0YkNi1RMCZBcHBseUZ1bmN0aW9uO0YnL0Y2USdub3JtYWxGJy8lJmZlbmNlR1EmZmFsc2VGJy8lKnNlcGFyYXRvckdGQC8lKXN0cmV0Y2h5R0ZALyUqc3ltbWV0cmljR0ZALyUobGFyZ2VvcEdGQC8lLm1vdmFibGVsaW1pdHNHRkAvJSdhY2NlbnRHRkAvJSdsc3BhY2VHUSYwLjBlbUYnLyUncnNwYWNlR0ZPLUkobWZlbmNlZEdGJDYkLUYjNihGKy1GLDYlUSJyRidGMkY1LUY5Ni1RIixGJ0Y8L0Y/USZ1bnNldEYnL0ZCRjQvRkRGaG4vRkZGaG4vRkhGaG4vRkpGaG4vRkxGaG5GTS9GUVEsMC4zMzMzMzMzZW1GJy1GLDYlUSgmdGhldGE7RicvRjNGQEY8RitGPEY8LUY5Ni1RIj1GJ0Y8Rj5GQUZDRkVGR0ZJRksvRk5RLDAuMjc3Nzc3OGVtRicvRlFGaW8tSSNtbkdGJDYkUSI1RidGPC1GOTYtUTEmSW52aXNpYmxlVGltZXM7RidGPEY+RkFGQ0ZFRkdGSUZLRk1GUC1GIzYmLUYsNiVRJGNvc0YnRjJGNUY4LUZTNiQtRiM2JEZhb0Y8RjxGPC1GOTYtUSIuRidGPEY+RkFGQ0ZFRkdGSUZLRk1GUEY8 The point of this function is that in any direction through the origin it is well behaved, in fact it is linear. However the tangent lines through the origin do not turn into a plane. rcos5theta := (x,y)-> piecewise(x = 0,0,(x^5-10*x^3*y^2+5*x*y^4)/(x^2+y^2)^2); rcos5theta(x,y); rcos5thetapolar := (r,theta) -> r*cos(5*theta); rcos5thetapolar(r,theta); plot3d(rcos5theta(x,y),x=-1..1,y=-1..1, axes=boxed, style=patchcontour); plot3d([r,theta,rcos5thetapolar(r,theta)],r=0..1,theta=0..2*Pi,coords=cylindrical,axes=boxed,grid=[50,50],style=patchcontour); We now repeat the preliminary work we did on f with our new function. Starting at the origin we can compute the directional derivatives and the gradient. rcos5theta := (x,y) -> (x^5-10*x^3*y^2+5*x*y^4)/(x^2+y^2)^2; xval :=0: yval:= 0: zval := limit(limit(rcos5theta(x,y),x=xval),y=yval); mx := limit(limit(diff(rcos5theta(x,y),x),x=xval),y=yval); my := limit(limit(diff(rcos5theta(x,y), y),x=xval),y=yval); gradvec := <mx, my>; unitgradient := gradvec/sqrt(gradvec.gradvec); gradientderiv := mx*unitgradient[1]+my*unitgradient[2]; As we did above with f, we construct a graph with the function in red, the gradient in green, a plane containing the gradient in yellow, and a tangent line to the surface in that plane in blue. surf:= plot3d(rcos5theta(x,y), x=xval-2..xval+2, y=yval-2..yval+2, axes=boxed, color=red, style = patchcontour): gradientpath :=spacecurve([xval+t*unitgradient[1], yval+t*unitgradient[2], rcos5theta(xval+t*unitgradient[1], yval+t*unitgradient[2])], t=-2..2, color=blue, thickness=2): cutplane := plot3d([xval+u*unitgradient[1], yval+u*unitgradient[2],zval+v], u=-2..2,v=-5..5, color=yellow, style=patchnogrid): gradline :=spacecurve( [xval+t*unitgradient[1], yval+t*unitgradient[2], zval+t*gradientderiv], t=0..1, color=green, thickness=3): display3d({cutplane, surf, gradientpath, gradline}); So far, so good. Now we want to plot the surface in red, the tangent plane in yellow, and a blue ring of points that are obtained by finding directional derivatives in each direction. tanplane:= plot3d(zval+mx*(x)+my*(y), x=-2..2, y=-2..+2, axes=boxed, color=yellow, style = patchnogrid): ddera := theta -> limit( (rcos5theta(xval+t*cos(theta), yval+t*sin(theta))-zval)/t, t=0); tanring :=spacecurve([xval+cos(theta), yval+sin(theta), zval+ddera(theta)], theta=0..2*Pi, color=blue, thickness=2): display3d({surf, tanplane, tanring,gradline,gradientpath}, view=[-2..2, -2..2, -4..4]); This picture looks all messed up. The tangent plane does not look like a tangent plane. The ring of points on tangent lines do not line up into a ring and the tangent lines do not form a plane.