Partial Derivatives, Gradients, and Plotting Level Curves
Here we will explore how to compute partial derivatives and gradients in Maple (and thus find linearizations of functions). We will also look at plotting level curves (contours), level surfaces, gradient vectors, tangent planes and normal lines.
Maple worksheet: contours.mw
> | restart;
with(plots): with(VectorCalculus): |
Level Curves (i.e. Contours) and Level Surfaces
Consider a function . For any constant we can consider the collection of points satisfying the equation: . This collection of points is generally called a level surface. When we generically have a (true 2-dimensional) surface. For example: The level surface of at level is the unit sphere (the sphere of radius 1 centered at the origin). When we generically have a curve. We call these level curves or contours. For example: The level curves of are parabolas: . A graph of (some of) the level curves of a function is called a contour plot (it looks like a topographical map).
Example: Let's plot of the surface and several horizontal planes. The curves of intersection are level curves (or contours) at levels and 1.
> | mySurface := implicitplot3d(z=(1/4)*x^2-(1/9)*y^2, x=-3..3, y=-3..3, z=-1.1..1.1, numpoints=2000, color=grey):
myLevels := seq(plot3d(-1+(1/2)*i, x=-3..3, y=-3..3, transparency=0.35), i=0..4): display({mySurface,myLevels},orientation=[45,45],viewpoint=circleleft); |
The "contourplot" command plots level curves of a given function.
> | contourplot((1/4)*x^2-(1/9)*y^2, x=-3..3, y=-3..3, contours=[-1,-1/2,0,1/2,1]); |
The "contourplot3d" function plots surfaces marked by contours. Notice with the current plot options the surface is colored in a different color between each consecutive pair of contours.
> | contourplot3d((1/4)*x^2-(1/9)*y^2, x=-3..3, y=-3..3, contours=[-1,-1/2,0,1/2,1], filledregions=true, axes=boxed, viewpoint=circleleft); |
Example: Consider . Let's use "contourplot3d" to plot over the rectangular region and .
> | g := (x,y) -> sin(x^2+y^2/4)/(x^2+y^2):
'g(x,y)' = g(x,y); contourplot3d(g(x,y), x=-Pi..Pi, y=-Pi..Pi, contours=5, filledregions=true, coloring=[blue,green], numpoints=2000,viewpoint=circleleft); |
Example: A Hyperbolic Paraboloid.
> | f := (x,y) -> x^2-y^2:
'f(x,y)' = f(x,y); plot3d(f(x,y),x=-2..2,y=-2..2,axes=boxed,viewpoint=circleleft); |
Let's plot this again, but now with a domain equal to (the inside of an ellipse).
> | plot3d(f(x,y),x=-3..3,y=-2*sqrt(1-x^2/3^2)..2*sqrt(1-x^2/3^2),title="A Pringle Chip",viewpoint=circleleft,color=tan); |
Next, let's draw some contours. We can specify specific contours (for example, drawing contours where z = -3, z = 0, z = 1) or just have Maple draw a bunch of contours like the second example (where Maple is told to draw 15 contours).
> | contourplot(f(x,y),x=-2..2,y=-2..2,contours=[-3,0,1]);
contourplot(f(x,y),x=-2..2,y=-2..2,contours=15); |
"contourplot3d" will draw the contours each at their proper z-level, so we get a 3D plot. "filledregions=true" make Maple fill in the surface in between the level curves.
> | contourplot3d(f(x,y),x=-2..2,y=-2..2,filledregions=true,contours=15,axes=boxed,viewpoint=circleleft); |
Example: Consider the function . Let's use plot3d, contourplot, and contourplot3d generate three different plots of this surface.
> | f := (x,y) -> y*exp(-x^2*y^4)+sin(x):
'f(x,y)' = f(x,y); plot3d(f(x,y),x=-2..2,y=-2..2,axes=framed,color=green,orientation=[35,80,0],viewpoint=circleleft); contourplot(f(x,y),x=-2..2,y=-2..2,contours=5); contourplot3d(f(x,y),x=-2..2,y=-2..2,filledregions=true,coloring=[blue,red],axes=boxed,contours=[-2,-1,0,1,2],orientation=[35,80,0],viewpoint=circleleft); |
Example: Consider the function . The graph of this function would be a hyper-surface in 4-dimensional space. However, if we set equal to a constant, (generically) we get a surface in 3-dimensional space. Such a surface is a level surface of . First, let's define and print off the equations defining level surfaces at levels 9, 4, and 1.
> | f := (x,y,z) -> x^2+y^2/4+z^2/9:
'f(x,y,z)' = f(x,y,z); f(x,y,z)=9; f(x,y,z)=4; f(x,y,z)=1; |
(1) |
Let's plot these surfaces together. Since these are nested ellipsoids, I'll make the outer ones somewhat transparent so we can "see inside".
> | A := implicitplot3d(f(x,y,z)=9,x=-3..3,y=-6..6,z=-9..9,color=black,transparency=0.9):
B := implicitplot3d(f(x,y,z)=4,x=-2..2,y=-4..4,z=-6..6,color=green,transparency=0.8): C := implicitplot3d(f(x,y,z)=1,x=-1..1,y=-2..2,z=-3..3,color=red,transparency=0): display({A,B,C},scaling=constrained,axes=boxed,viewpoint=circleleft); |
The following code animates is sequence of plots of level surfaces: where . I have also set the color so it changes with .
> | N := 50:
level := i -> c=evalf(9*i/N,3): for i from 1 to N do levelPlot[i] := implicitplot3d(f(x,y,z)=9*i/N,x=-sqrt(9*i/N)..sqrt(9*i/N),y=-2*sqrt(9*i/N)..2*sqrt(9*i/N),z=-3*sqrt(9*i/N)..3*sqrt(9*i/N),color=RGB(1-i/N,1-i/N,i/N),numpoints=1000,title=level(i)): end do: display(seq(levelPlot[i],i=1..N),insequence=true,scaling=constrained,axes=boxed); |
Partial Derivatives and Gradients
Partial derivatives? Just differentiate. To compute the gradient of a function use: "Gradient(f(variables),[list of variables]);".
Example:
> | f := (x,y) -> x^2*y^3+sin(x+5*y)+x*exp(x^2*y^5):
'f(x,y)' = f(x,y); |
(2) |
First partials...
> | diff(f(x,y),x);
diff(f(x,y),y); |
(3) |
Second partials...
> | diff(f(x,y),x,x);
diff(f(x,y),x,y)=diff(f(x,y),y,x); diff(f(x,y),y,y); |
(4) |
A random fifth order partial:
> | diff(f(x,y),x,y,y,x,y); |
(5) |
10 partials with respect to followed by 5 with respect to y then x once more...
> | diff(f(x,y),x$10,y$5,x); |
(6) |
Example: Let's linearize at (-2,5). To do this we need the function's value at (-2,5) along with the first partials evaluated at (-2,5).
> | f := (x,y) -> x^2*y+y^3-3:
'f(x,y)' = f(x,y); 'f(-2,5)' = f(-2,5); f_x(-2,5)=subs(y=5,subs(x=-2,diff(f(x,y),x))); f_y(-2,5)=subs(y=5,subs(x=-2,diff(f(x,y),y))); L := (x,y) -> 142 + (-20)*(x+2) + (79)*(y-5): 'L(x,y)' = L(x,y); |
(7) |
The linearization should be a decent approximation of near , so (-1.9,5.3) should be approxiamately .
> | 'f(-1.9,5.3)' = f(-1.9,5.3);
'L(-1.9,5.3)' = L(-1.9,5.3); |
(8) |
Close but not exactly right. But we should expect the f(x,y) and L(x,y) don't match since f(x,y) isn't linear! Let's plot the surface and its linearization together.
> | fPlot := plot3d(f(x,y),x=-16..12,y=-9..19,color=blue):
LPlot := plot3d(L(x,y),x=-16..12,y=-9..19,color=red): display({fPlot,LPlot},orientation=[-26,52],viewpoint=circleleft); |
Now let's compute the gradient of our function...
> | gradf := Gradient(f(x,y),[x,y]); |
(9) |
Let's plug in the point (1,1/2).
> | pt := <1,1/2>;
vec := evalVF(gradf,pt); |
(10) |
The directional derivative of f in the direction at the point (1,1/2) is...
> | vec . <-1/sqrt(2), 1/sqrt(2)>; |
(11) |
Alternatively, we could use the VectorCalculus package function "DirectionalDiff". The "subs" command substitutes in the appropriate values for x and y.
> | subs([x=1,y=1/2],DirectionalDiff(f(x,y),<-1/sqrt(2),1/sqrt(2)>,[x,y])); |
(12) |
Here is the contour plot and the gradient vector plotted together. I'll use the option "scaling=constrained" so the graph isn't streched. If the graph is skewed, then the gradient won't look perpendicular to the level curve. Notice also the contourplot option "contours=40". We can specify how many level curves to plot. We could also specify "contours=[0,1,2,3]".
> | conPlot := contourplot(f(x,y),x=-2.5..2.5,y=-2.5..2.5,contours=40):
vecPlot := arrow(pt,vec,shape=harpoon,color=magenta): display({conPlot,vecPlot},scaling=constrained); |
Let's consider our surface z = f(x,y) as the level surface z - f(x,y) = 0.
> | F := (x,y,z) -> z-f(x,y):
'F(x,y,z)' = F(x,y,z); implicitplot3d(F(x,y,z)=0,x=-2.5..2.5,y=-2.5..2.5,z=-35..25,axes=boxed,viewpoint=circleleft); |
The gradient of F(x,y,z) evaluated at a point (a,b,c) on the level surface gives a normal vector for the plane tangent to F at that point.
> | gradF := Gradient(F(x,y,z),[x,y,z]);
z=f(0,-1); |
(13) |
The point (0,-1,-4) is on the level surface since...
> | F(0,-1,-4)=0; |
(14) |
We'll find the gradient vector at that point...
> | pt := <0,-1,-4>;
vec := evalVF(gradF,pt); |
(15) |
Now let's normalize our vector (so it doesn't stick out so far) and plot the surface,
its tangent plane and gradient vector all together.
> | n := Normalize(vec);
tPlaneEqn := vec.(<x,y,z> - pt) = 0; plotP := implicitplot3d(tPlaneEqn,x=-2.5..2.5,y=-1.5..0.75,z=-5..0,color=blue): plotF := implicitplot3d(F(x,y,z)=0,x=-2.5..2.5,y=-1.5..0.75,z=-5..0,color=red): plotV := arrow(pt,n,shape=harpoon,color=green,thickness=3): display({plotP,plotF,plotV},scaling=constrained,axes=boxed,orientation=[-90,5,-90],viewpoint=circleleft); |
Example: Define a function . Let's consider the level surface .
> | F := (x,y,z) -> x^2/4+y^2/9+z^2/4:
'F(x,y,z)' = F(x,y,z); F(x,y,z)=1; |
(16) |
First, we'll verify that the point is on the level surface . Then we'll use the gradient operator to find a normal vector for the level surface at this point (we'll call this vector ).
> | F(sqrt(2),0,-sqrt(2))=1;
n := evalVF(Gradient(F(x,y,z),[x,y,z]),<sqrt(2),0,-sqrt(2)>); |
(17) |
Finally, let's graph the level surface together with the its tangent plane and normal line at the point .
> | tangentPlane := n.(<x,y,z>-<sqrt(2),0,-sqrt(2)>)=0;
normalLine := <sqrt(2),0,-sqrt(2)> + n*t; surfPlot := implicitplot3d(F(x,y,z)=1,x=-4..4,y=-4..4,z=-4..4,numpoints=5000): tanPlot := plot3d(solve(tangentPlane,z),x=-4..4,y=-4..4): normPlot := spacecurve(normalLine,t=-8..3,thickness=2,color=blue): display({surfPlot,tanPlot,normPlot},orientation=[-44,73],viewpoint=circleleft); |
Example: Here we will graph the hyberboloid of one sheet together with its tagent plane and normal line at the point .
> | F := (x,y,z) -> x^2/4+y^2-z^2/9:
'F(x,y,z)' = F(x,y,z); F(2,-1,3)=1; |
(18) |
Next, let's generate the normal vector at the point .
> | n := evalVF(Gradient(F(x,y,z),[x,y,z]),<2,-1,3>); |
(19) |
Next, we need equations for the tangent plane and the normal line. Both the tangent plane and normal line at (2,-1,3) pass through this point. The gradient vector at this point provides a normal vector for the tangent plane and a direction vector for the normal line.
> | tPlane := n.(<x,y,z>-<2,-1,3>)=0;
nLine := <2,-1,3>+n*t; |
(20) |
Now let's make our plots and display them together.
> | levelSurface := implicitplot3d(F(x,y,z)=1,x=-5..5,y=-5..5,z=-8..8,numpoints=5000):
tangentPlot := plot3d(solve(tPlane,z),x=-4..4,y=-3..2,color=blue): normalPlot := spacecurve(nLine,t=-3..3,color=red,thickness=3): display({levelSurface,normalPlot,tangentPlot},scaling=constrained,orientation=[-90,71],viewpoint=circleleft); |
Example: Let's plot over the circular disk: . Then we'll plot some of its level curves and gradient vectors.
> | solve(x^2+y^2=2^2,y); |
(21) |
> | f := (x,y) -> x^2/9+y^2/4:
'f(x,y)'=f(x,y); plot3d(f(x,y),x=-2..2,y=-sqrt(4-x^2)..sqrt(4-x^2),scaling=constrained,axes=boxed,viewpoint=circleleft); |
Next, let's use "conplot" and "gradplot" to plot level curves of along with some of its gradient vectors. Specifically let's draw contours for levels and 2.5.
> | conPlot := contourplot(f(x,y), x=-3..3, y=-3..3, contours=[0.02,0.1,0.5,1,1.5,2.5], filledregions=true, coloring=[red,yellow]):
gradPlot := gradplot(f(x,y), x=-3..3, y=-3..3, grid=[7,7],arrows=SLIM): display({conPlot,gradPlot},axes=none); |
Example: Let . We will use "contourplot" to plot some of f(x,y)'s level curves. Specifically let's plot the level curves where z equals -5, -4, -3, ..., 9, and 10. The plot option "numpoints=5000" makes sure the graphs don't look too rough.
Note: We will need this plot later, thus the assignment and display command.
> | f := (x,y) -> ln(4*x^2+y^2):
'f(x,y)' = f(x,y); conPlot := contourplot(f(x,y),x=-3..3,y=-3..3,contours=[seq(i,i=-5..10)],numpoints=5000): display(conPlot); |
Alternatively, we could have used the command:
[> conPlot := contourplot(f(x,y),x=-3..3,y=-3..3,contours=[-5,-4,-,3,-2,-1,0,1,2,3,4,5,6,7,8,9,10],numpoints=5000):
From this plot we can see that the level curves of are ellipses centered at the origin.
Next, let's compute the gradient of f(x,y) using "Gradient". Then use "evalVF" to evaluate the gradient at the points:
= (1,0), = (0,-1), and = (1,-1).
> | gradf := Gradient(f(x,y),[x,y]);
p[1] := <1,0>; v[1] := evalVF(gradf,p[1]); p[2] := <0,-1>; v[2] := evalVF(gradf,p[2]); p[3] := <1,-1>; v[3] := evalVF(gradf,p[3]); |
(22) |
Next, let's create plots for all 3 gradient vectors based at their corresponding points using the "arrow" command. Notice how the gradient vectors are perpendicular to level curves (and point toward "higher ground").
> | v1Plot := arrow(p[1],v[1],shape=arrow,color=red,thickness=3):
v2Plot := arrow(p[2],v[2],shape=arrow,color=blue,thickness=3): v3Plot := arrow(p[3],v[3],shape=arrow,color=green,thickness=3): display({v1Plot,v2Plot,v3Plot,conPlot},scaling=constrained); |
Example: Let's define the function and then plot the level surface using "implicitplot3d".
Note: We will need this plot later, thus the assignment and display command.
> | F := (x,y,z) -> x^2+y^2+z^2:
'F(x,y,z)'=F(x,y,z); spherePlot:=implicitplot3d(F(x,y,z)=4^2,x=-4..4,y=-4..4,z=-4..4): display(spherePlot); |
Let's verify that the point is on the level surface .
> | F(-2,2*sqrt(2),2)=4^2; |
(23) |
Next, we will compute the gradient of and evalute it at the point .
> | gradF := Gradient(F(x,y,z),[x,y,z]);
pt := <-2,2*sqrt(2),2>; vec := evalVF(gradF,pt); |
(24) |
Next, let's plot the gradient vector based at and the level surface together.
> | gradPlot := arrow(pt,vec,shape=arrow,color=red,thickness=3):
display({spherePlot,gradPlot},scaling=constrained,viewpoint=circleleft); |
Example: Let's plot level curves of a function along with some gradient vectors. We will see that the gradient vectors are orthogonal to the level curves. Then we'll view our surface as a level surface of a 3 variable function. The gradient vectors of this 3 variable function will give us vectors normal to the surface itself (i.e. normals for tangent planes).
> | h := (x,y) -> y^2/4-x^2/9:
'h(x,y)' = h(x,y); |
(25) |
Define to be the gradient vector at the point , let be the gradient vector at the point , and let be the gradient vector at .
> | gradh := Gradient(h(x,y),[x,y]);
u := evalVF(gradh,<-1,-1>); v := evalVF(gradh,< 2, 0>); w := evalVF(gradh,< 0, 1>); |
(26) |
Next, let's graph the contours of the surface (in 2-dimensions) along with the gradient vectors and .
> | conPlot := contourplot(h(x,y),x=-2..2,y=-2..2,contours=15):
uPlot := arrow(<-1,-1>,u,shape=arrow,thickness=2,color=black): vPlot := arrow(< 2, 0>,v,shape=arrow,thickness=2,color=blue): wPlot := arrow(< 0, 1>,w,shape=arrow,thickness=2,color=green): display({uPlot,vPlot,wPlot,conPlot}); |
Now let's compute normal vectors for the surface at the points and . To do this we will consider so that is equivalent to . Thus the normals for the tangents come from the gradient of (the gradient of gives us normals for its level surfaces).
> | F := (x,y,z) -> z-h(x,y):
'F(x,y,z)' = F(x,y,z); gradF := Gradient(F(x,y,z),[x,y,z]); nU := evalVF(gradF,<-1,-1,h(-1,-1)>); nV := evalVF(gradF,< 2, 0,h( 2, 0)>); nW := evalVF(gradF,< 0, 1,h( 0, 1)>); |
(27) |
Finally, let's plot the surface in 3-dimensions using " " (turning on the option which fills in the surface between the contours). We'll also plot the normal vectors we just computed and display everything together.
> | con3dPlot := contourplot3d(h(x,y),x=-2..2,y=-2..2,contours=15,filled=true):
uPlot := arrow(<-1,-1,h(-1,-1)>,nU,shape=arrow,thickness=2,color=black): vPlot := arrow(< 2, 0,h( 2, 0)>,nV,shape=arrow,thickness=2,color=blue): wPlot := arrow(< 0, 1,h( 0, 1)>,nW,shape=arrow,thickness=2,color=green): display({uPlot,vPlot,wPlot,con3dPlot},orientation=[-25,65,-15],scaling=constrained,viewpoint=circleleft); |