Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

Lecture slides for UCLA LS 30B, Spring 2020

Views: 14466
License: GPL3
Image: ubuntu2004
Kernel: SageMath 9.1
def axes3d(x_range, y_range, z_range, **options): """Draw x, y, and z axes in 3D, and optionally a grid on the xy-plane 'x_range' should have the form (x, xmin, xmax), and likewise for 'y_range' and 'z_range'. Here the 'x' can be either a symbolic variable, or a string. Either way, it is only used as a label for the corresponding axis. Options: 'origin' - Locate the axes so that they all intersect at this point (default (0,0,0)) 'grid' - Whether or not to draw a grid on the xy-plane (default True) All other options are as for the 'line3d' and 'arrow3d' commands, and are passed directly on to them. """ x0, y0, z0 = options.pop("origin", (0, 0, 0)) grid = options.pop("grid", True) gridoptions = options.copy() options.setdefault("color", "black") gridoptions.setdefault("color", "gray") x, xmin, xmax = x_range y, ymin, ymax = y_range z, zmin, zmax = z_range xmin, xmax = min(x0, xmin), max(x0, xmax) ymin, ymax = min(y0, ymin), max(y0, ymax) zmin, zmax = min(z0, zmin), max(z0, zmax) p = Graphics() p += arrow3d((xmin, y0, z0), (xmax, y0, z0), width=1, **options) p += arrow3d((x0, ymin, z0), (x0, ymax, z0), width=1, **options) p += arrow3d((x0, y0, zmin), (x0, y0, zmax), width=1, **options) p += text3d(str(x), (xmax + (xmax - xmin)*0.05, y0, z0), **options) p += text3d(str(y), (x0, ymax + (ymax - ymin)*0.05, z0), **options) p += text3d(str(z), (x0, y0, zmax + (zmax - zmin)*0.05), **options) xgridsize = 10**int(log(0.68*max(-xmin, xmax), 10)) ygridsize = 10**int(log(0.68*max(-ymin, ymax), 10)) zgridsize = 10**int(log(0.68*max(-zmin, zmax), 10)) gridmin = ceil(xmin/xgridsize) * xgridsize for xval in srange(gridmin, xmax+xgridsize/100.0, xgridsize): #p += text3d("{:.0f}".format(float(xval)), (xval, ygridsize/5.0, 0), **options) if grid: p += line3d(((xval, ymin, 0), (xval, ymax, 0)), thickness=1, **gridoptions) gridmin = ceil(ymin/ygridsize) * ygridsize for yval in srange(gridmin, ymax+ygridsize/100.0, ygridsize): #p += text3d("{:.0f}".format(float(yval)), (xgridsize/5.0, yval, 0), **options) if grid: p += line3d(((xmin, yval, 0), (xmax, yval, 0)), thickness=1, **gridoptions) gridmin = ceil(zmin/zgridsize) * zgridsize #for zval in srange(gridmin, zmax+zgridsize/100.0, zgridsize): #p += text3d("{:.0f}".format(float(zval)), (xgridsize/5.0, 0, zval), **options) return p
x, y, z = var("x, y, z") f(x, y) = 0.5 + sin(x/1.5)*cos(y/2) + 1 - 2*cos(x/3)*sin(y/5) + 2 (x0, y0) = (1, -1) z0 = f(x0, y0) df_dx(x, y) = diff(f(x, y), x) df_dy(x, y) = diff(f(x, y), y) Deltaf_x(Deltax) = df_dx(x0, y0) * Deltax Deltaf_y(Deltay) = df_dy(x0, y0) * Deltay Deltaf(Deltax, Deltay) = df_dx(x0, y0) * Deltax + df_dy(x0, y0) * Deltay
axes = axes3d((x, -6.5, 6.5), (y, -6.5, 6.5), (z, -0.1, 6)) surface = plot3d(f(x, y), (x, -6, 6), (y, -6, 6), plot_points=(40,40), color="lightskyblue", opacity=0.85) pointXY = sphere((x0, y0, 0), 0.17, color="red") point0 = sphere((x0, y0, z0), 0.17, color="darkgreen") tangent_plane = parametric_plot3d((x0 + Deltax, y0 + Deltay, z0 + Deltaf_x(Deltax) + Deltaf_y(Deltay)), (Deltax, -3, 3), (Deltay, -3, 3), color="plum", opacity=0.5) baseplot = axes + surface + point0

Learning goals:

  • Know what the partial derivatives of a function f(X,Y)f(X, Y) are, and roughly how to compute them.

  • Be able to compute a linear approximation to a function f(X,Y)f(X, Y), assuming that you know those partial derivatives.

Recall the set-up from a previous video:

We have a system of differential equations {X′=f(X,Y)Y′=g(X,Y) \begin{cases} X' = f(X,Y) \\ Y' = g(X,Y) \end{cases}

It has an equilibrium point at (X∗,Y∗)(X^*, Y^*).

We want to find the formula for the linear approximation to the function ff at (X∗,Y∗)(X^*, Y^*).

The graph of the function f(X,Y)f(X,Y) is some surface:

(axes + surface).show(aspect_ratio=(1,1,1), frame=False)

Here's the point (X∗,Y∗)(X^*, Y^*):

(axes + pointXY).show(aspect_ratio=(1,1,1), frame=False)

And here's the corresponding point on the graph of ff:
That point is (X∗,Y∗,f(X∗,Y∗))(X^*, Y^*, f(X^*, Y^*)).

(baseplot + pointXY).show(aspect_ratio=(1,1,1), frame=False)

Suppose we choose another point near (X∗,Y∗)(X^*, Y^*), but only by changing XX.

Delta_X = 0.7 p = Graphics() + axes + pointXY p += sphere((x0 + Delta_X, y0, 0), 0.17, color="fuchsia") p.show(aspect_ratio=(1,1,1), frame=False)

Here's the point corresponding to that on the graph of ff:

p = Graphics() + baseplot p += sphere((x0 + Delta_X, y0, f(x0 + Delta_X, y0)), 0.17, color="fuchsia") p.show(aspect_ratio=(1,1,1), frame=False)

Here are all the points we could get if we only change XX, and hold YY constant.

p = Graphics() + baseplot p += parametric_plot3d((x, y0, z), (x, -6, 6), (z, 0, 5), color="red", opacity=0.7) p.show(aspect_ratio=(1,1,1), frame=False)

That cross-section, viewed with just the XX and ZZ axes (since YY is being held constant):

@interact(show_tangent=checkbox(False, label="Show tangent line")) def tangent_x(show_tangent): slope = df_dx(x0, y0) p = plot(f(x, y0), (x, -6, 6), color="lightskyblue", thickness=2) p += point((x0, z0), size=40, color="green") if show_tangent: p += line(((x0 - 3, z0 - slope*3), (x0 + 3, z0 + slope*3)), color="red") p.show(axes_labels=("$X$", "$Z$"), ymin=0, ymax=6.5, aspect_ratio=1, figsize=6)

Here's that same tangent line, on the surface:

p = Graphics() + baseplot p += parametric_plot3d((x0 + Deltax, y0, z0 + Deltaf_x(Deltax)), (Deltax, -4, 4), color="red", opacity=0.85) p.show(aspect_ratio=(1,1,1), frame=False)

Conclusion so far:

The slope, ΔZΔX\displaystyle \frac{\Delta Z}{\Delta X}, of that tangent line can be found by setting Y=Y∗Y = Y^* (that is, plugging the constant Y∗=−1Y^* = -1 into the equation for ff) and then computing the derivative with respect to XX at X∗=1X^* = 1.

This slope is called the partial derivative of ff with respect to XX, at the point (X∗,Y∗)(X^*, Y^*).

Definition: The partial derivative of the function f(X,Y)f(X, Y) at the point (X∗,Y∗)(X^*, Y^*) is found by keeping YY constant, and taking the derivative of ff with respect to XX.

Notation: ∂f∂X∣(X∗,Y∗)=\displaystyle \left. \frac{\partial f}{\partial X} \right|_{(X^*, Y^*)} = the partial derivative of ff with respect to XX at (X∗,Y∗)(X^*, Y^*).

Tying this back in to linear approximation:

@interact(show_second=checkbox(False, label="Second point"), show_deltas=checkbox(False, label=r"$\Delta X$, $\Delta f$"), show_result=checkbox(False, label="Linear approx.")) def approx_x(show_second, show_deltas, show_result): slope = df_dx(x0, y0) p = plot(f(x, y0), (x, -2, 5), color="lightskyblue", thickness=2) if show_second: p += point((x0, 0), size=40, color="red") p += point((x0 + Delta_X, 0), size=40, color="fuchsia") p += point((x0 + Delta_X, f(x0 + Delta_X, y0)), size=40, color="fuchsia") p += point((x0, z0), size=40, color="green") p += line(((x0 - 3, z0 - slope*3), (x0 + 3, z0 + slope*3)), color="red") if show_deltas: p += line(((x0, z0), (x0 + Delta_X, z0), (x0 + Delta_X, f(x0 + Delta_X, y0))), color="darkgreen", linestyle="dashed") p += text(r"$\Delta X$", (x0 + Delta_X/2, z0 - 0.2), fontsize=14, color="darkgreen") p += text(r"$\Delta f$", (x0 + Delta_X + 0.3, (z0 + f(x0 + Delta_X, y0))/2), fontsize=14, color="darkgreen") if show_result: p += text(r"$\Delta f \approx \left( \left. \frac{\partial f}{\partial X} \right|_{_{(X^*, Y^*)}} \right) \cdot \Delta X$", (x0 + 1, (z0 + 2)/2), fontsize=20, color="black") p.show(axes_labels=("$X$", "$Z$"), ymin=2, ymax=6, aspect_ratio=1, figsize=6)

Suppose we choose another point near (X∗,Y∗)(X^*, Y^*), but this time only changing YY.

Delta_Y = 0.8 p = Graphics() + axes + pointXY p += sphere((x0, y0 + Delta_Y, 0), 0.17, color="fuchsia") p.show(aspect_ratio=(1,1,1), frame=False)

Here's the point corresponding to that on the graph of ff:

p = Graphics() + baseplot p += sphere((x0, y0 + Delta_Y, f(x0, y0 + Delta_Y)), 0.17, color="fuchsia") p.show(aspect_ratio=(1,1,1), frame=False)

Here are all the points we could get if we only change YY, and hold XX constant.

p = Graphics() + baseplot p += parametric_plot3d((x0, y, z), (y, -6, 6), (z, 0, 5), color="red", opacity=0.7) p.show(aspect_ratio=(1,1,1), frame=False)

That cross-section, viewed with just the YY and ZZ axes (since XX is being held constant):

@interact(show_tangent=checkbox(False, label="Show tangent line")) def tangent_y(show_tangent): slope = df_dy(x0, y0) p = plot(f(x0, y), (y, -6, 6), color="lightskyblue", thickness=2) p += point((y0, z0), size=40, color="green") if show_tangent: p += line(((y0 - 3, z0 - slope*3), (y0 + 3, z0 + slope*3)), color="red") p.show(axes_labels=("$Y$", "$Z$"), ymin=0, ymax=6.5, aspect_ratio=1, figsize=6)

Here's that same tangent line, on the surface:

p = Graphics() + baseplot p += parametric_plot3d((x0, y0 + Deltay, z0 + Deltaf_y(Deltay)), (Deltay, -4, 4), color="red", opacity=0.85) p.show(aspect_ratio=(1,1,1), frame=False)

Another conclusion:

The slope, ΔZΔY\displaystyle \frac{\Delta Z}{\Delta Y}, of that tangent line can be found by setting X=X∗X = X^* (that is, plugging the constant X∗=1X^* = 1 into the equation for ff) and then computing the derivative with respect to YY at Y∗=−1Y^* = -1.

This slope is called the partial derivative of ff with respect to YY, at the point (X∗,Y∗)(X^*, Y^*).

Tying this back in to linear approximation:

@interact(show_second=checkbox(False, label="Second point"), show_deltas=checkbox(False, label=r"$\Delta Y$, $\Delta f$"), show_result=checkbox(False, label="Linear approx.")) def approx_y(show_second, show_deltas, show_result): slope = df_dy(x0, y0) p = plot(f(x0, y), (y, -5, 2), color="lightskyblue", thickness=2) if show_second: p += point((y0, 0), size=40, color="red") p += point((y0 + Delta_Y, 0), size=40, color="fuchsia") p += point((y0 + Delta_Y, f(x0, y0 + Delta_Y)), size=40, color="fuchsia") p += point((y0, z0), size=40, color="green") p += line(((y0 - 3, z0 - slope*3), (y0 + 3, z0 + slope*3)), color="red") if show_deltas: p += line(((y0, z0), (y0, f(x0, y0 + Delta_Y)), (y0 + Delta_Y, f(x0, y0 + Delta_Y))), color="darkgreen", linestyle="dashed") p += text(r"$\Delta Y$", (y0 + Delta_Y/2, f(x0, y0 + Delta_Y) - 0.2), fontsize=14, color="darkgreen") p += text(r"$\Delta f$", (y0 - 0.3, (z0 + f(x0, y0 + Delta_Y))/2), fontsize=14, color="darkgreen") if show_result: p += text(r"$\Delta f \approx \left( \left. \frac{\partial f}{\partial Y} \right|_{_{(X^*, Y^*)}} \right) \cdot \Delta Y$", (y0 - 1.4, (z0 + 2)/2), fontsize=20, color="black") p.show(axes_labels=("$Y$", "$Z$"), ymin=2, ymax=6, aspect_ratio=1, figsize=6)

Putting it all together:

We saw that when we kept YY constant and just made a small change ΔX\Delta X to the XX variable, the linear approximation was given by: Δf≈(∂f∂X∣(X∗,Y∗))⋅ΔX \Delta f \approx \left( \left. \frac{\partial f}{\partial X} \right|_{(X^*, Y^*)} \right) \cdot \Delta X

Similarly, when we kept XX constant and just made a small change ΔY\Delta Y to the YY variable, the linear approximation was: Δf≈(∂f∂Y∣(X∗,Y∗))⋅ΔY \Delta f \approx \left( \left. \frac{\partial f}{\partial Y} \right|_{(X^*, Y^*)} \right) \cdot \Delta Y

So if we make both small changes, ΔX\Delta X and ΔY\Delta Y, we should get Δf≈(∂f∂X∣(X∗,Y∗))⋅ΔX+(∂f∂Y∣(X∗,Y∗))⋅ΔY \Delta f \approx \left( \left. \frac{\partial f}{\partial X} \right|_{(X^*, Y^*)} \right) \cdot \Delta X + \left( \left. \frac{\partial f}{\partial Y} \right|_{(X^*, Y^*)} \right) \cdot \Delta Y

Conclusions:

  1. A function f(X,Y)f(X, Y) has not just a derivative, but two partial derivatives, one with respect to XX and another with respect to YY: ∂f∂Xand∂f∂Y \frac{\partial f}{\partial X} \qquad \text{and} \qquad \frac{\partial f}{\partial Y}

  2. To compute the partial derivative of ff with respect to XX at (X∗,Y∗)(X^*, Y^*), just hold YY constant (or even substitute the constant Y∗Y^* in place of YY), and take the derivative of ff with respect to XX. Likewise for the partial derivative of ff with respect to YY.

  3. The complete formula for the linear approximation of ff at (X∗,Y∗)(X^*, Y^*) is Δf≈(∂f∂X∣(X∗,Y∗))⋅ΔX+(∂f∂Y∣(X∗,Y∗))⋅ΔY \Delta f \approx \left( \left. \frac{\partial f}{\partial X} \right|_{(X^*, Y^*)} \right) \cdot \Delta X + \left( \left. \frac{\partial f}{\partial Y} \right|_{(X^*, Y^*)} \right) \cdot \Delta Y

Bonus content: Note that we just found two tangent lines to the surface at (X∗,Y∗)(X^*, Y^*):

p = Graphics() + baseplot p += parametric_plot3d((x0 + Deltax, y0, z0 + Deltaf_x(Deltax)), (Deltax, -4, 4), color="red", opacity=0.85) p += parametric_plot3d((x0, y0 + Deltay, z0 + Deltaf_y(Deltay)), (Deltay, -4, 4), color="red", opacity=0.85) p.show(aspect_ratio=(1,1,1), frame=False)

In fact, there are many tangent lines to the surface at (X∗,Y∗)(X^*, Y^*):

p = Graphics() + baseplot t = var("t") for theta in srange(0, pi, pi/10): a, b = cos(theta), sin(theta) color="red" if a == 1 or a == 0 else "blue" p += parametric_plot3d((x0 + a*t, y0 + b*t, z0 + a*Deltaf_x(t) + b*Deltaf_y(t)), (t, -4, 4), color=color, opacity=0.85) p.show(aspect_ratio=(1,1,1), frame=False)

All of them collectively form a plane, the tangent plane:

p = Graphics() + baseplot + tangent_plane p.show(aspect_ratio=(1,1,1), frame=False)

We will be able to use those two slopes of the two original tangent lines (the two partial derivatives) to find an equation for the tangent plane.

p = Graphics() + baseplot + tangent_plane p += parametric_plot3d((x0 + Deltax, y0, z0 + Deltaf_x(Deltax)), (Deltax, -4, 4), color="red", opacity=0.85) p += parametric_plot3d((x0, y0 + Deltay, z0 + Deltaf_y(Deltay)), (Deltay, -4, 4), color="red", opacity=0.85) p.show(aspect_ratio=(1,1,1), frame=False)