#set document(title: "4.1 The Gradient and Level Curves", author: "XYZ Homework") #set page(width: 8.5in, height: auto, margin: 1in) #import "@preview/cetz:0.5.2" #set text(font: ("STIX Two Text", "Libertinus Serif", "New Computer Modern"), size: 10.5pt, lang: "en") #show math.equation: set text(font: ("STIX Two Math", "New Computer Modern Math")) #set par(justify: true, leading: 0.62em, spacing: 0.9em) #set enum(spacing: 1.1em) // room between list items so tall inline fractions don't collide #set list(spacing: 1.1em) #set table(stroke: 0.5pt + rgb("#c7ccd3")) #let BLUE = rgb("#183B6F") // brand navy โ€” section bars + example/solution labels (white on navy 11.09:1) #let ORANGE = rgb("#A94509") // brand primary-700 โ€” AA-safe deep orange for TEXT (5.93:1 on white; raw brand #F37021 is 2.94:1 and must never carry text) #let RED = rgb("#DC2626") // brand error-600 #let GREEN = rgb("#059669") // brand success-600 (decoration only; small green text uses green-text #007942) #show heading.where(level: 1): it => block(width: 100%, above: 0pt, below: 16pt, fill: gradient.linear(BLUE, rgb("#2C5AA0")), inset: (x: 14pt, y: 12pt), radius: 3pt, text(fill: white, weight: "bold", size: 19pt, it.body)) #show heading.where(level: 2): it => block(width: 100%, above: 18pt, below: 10pt, fill: BLUE, inset: (x: 10pt, y: 6pt), radius: 2pt, text(fill: white, weight: "bold", size: 12pt, it.body)) #show heading.where(level: 3): it => text(fill: ORANGE, weight: "bold", size: 12.5pt, it.body) #show heading.where(level: 4): it => text(fill: BLUE, weight: "bold", size: 10.5pt, it.body) #let examplebox(label, title, body) = block(width: 100%, breakable: true, fill: rgb("#EFF1F5"), stroke: 0.5pt + rgb("#CFDDF0"), radius: 4pt, inset: 10pt, above: 12pt, below: 12pt)[ #block(below: 6pt)[#box(fill: BLUE, inset: (x: 6pt, y: 2pt), radius: 2pt, text(fill: white, weight: "bold", size: 8.5pt, label)) #h(0.4em) #strong[#title]] #body] // rail = decorative left rule (raw brand token); labelcolor = AA-safe label text shade #let notebox(label, rail, labelcolor, tint, body) = block(width: 100%, breakable: true, fill: tint, stroke: (left: 3pt + rail), inset: (left: 10pt, rest: 8pt), radius: (right: 4pt), above: 11pt, below: 11pt)[ #text(fill: labelcolor, weight: "bold", size: 7.5pt, tracking: 0.5pt)[#upper(label)] #linebreak() #body] #let solutionbox(body) = block(above: 4pt, below: 8pt)[ #text(fill: BLUE, weight: "bold", size: 8.5pt)[Solution] #linebreak() #body] #let figph(msg) = block(width: 100%, height: 60pt, fill: rgb("#f6f7f9"), stroke: (paint: rgb("#c7ccd3"), dash: "dashed"), radius: 4pt, inset: 10pt)[ #align(center + horizon, text(fill: rgb("#889"), style: "italic", size: 9pt, msg))] // Standardize inlined figure sizes: measure the natural CeTZ canvas, then scale to a // consistent envelope (aspect-aware; see build_typst.py FIG_* constants). Unlike the // print preamble, dimensions are FLOORED: in an editor a user can trim a figure to a // degenerate 1-D shape (a bare line), and w/h or tw/w would then divide by zero. #let _STD_W = 3.5 #let _WIDE_W = 5.6 #let _MAX_H = 3.4 #let _ASPECT_WIDE = 2.2 #let _UPSCALE_MAX = 1.15 #let stdfig(body) = context { let m = measure(body) let w = calc.max(m.width / 1in, 0.01) let h = calc.max(m.height / 1in, 0.01) let tw = if w / h > _ASPECT_WIDE { _WIDE_W } else { _STD_W } let s = calc.min(tw / w, _MAX_H / h, _UPSCALE_MAX) align(center, box(scale(x: s * 100%, y: s * 100%, reflow: true, body))) } #show figure: set block(breakable: false) #set figure(gap: 8pt) #show figure.caption: set text(size: 8.5pt, fill: rgb("#555")) == 4.1#h(0.6em)The Gradient and Level Curves #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Objectives] - Assemble the gradient vector from the partial derivatives and use it to compute directional derivatives. - Verify on a contour-and-arrows map that the gradient crosses every level curve at a right angle. - Connect arrow direction to steepest ascent and arrow strength to contour spacing. ] Partial derivatives measure slope in two special directions. To get every other direction, bundle them into the #strong[gradient vector] #math.equation(block: false, alt: "โˆ‡ f equals open parenthesis f sub x , f sub y close parenthesis")[$โˆ‡ f = ( f_(x) , f_(y) )$]. The slope of the surface in the direction of a unit vector #math.equation(block: false, alt: "๐ฎ")[$๐ฎ$] โ€” the #strong[directional derivative] โ€” is then a dot product: #math.equation(block: true, alt: "D sub ๐ฎ f equals โˆ‡ f times ๐ฎ ,")[$D_(๐ฎ) f = โˆ‡ f ยท ๐ฎ ,$] largest when #math.equation(block: false, alt: "๐ฎ")[$๐ฎ$] points along #math.equation(block: false, alt: "โˆ‡ f")[$โˆ‡ f$] (value #math.equation(block: false, alt: "โ€– โˆ‡ f โ€–")[$โ€– โˆ‡ f โ€–$]), zero when #math.equation(block: false, alt: "๐ฎ")[$๐ฎ$] is perpendicular to it. Those two facts give the gradient its geometry: it points straight uphill, at the rate #math.equation(block: false, alt: "โ€– โˆ‡ f โ€–")[$โ€– โˆ‡ f โ€–$], and it crosses the level curve through its point at a right angle. The figure lets you audit that claim wholesale. {"camera":{"fov":50,"position":\[0.5,9,0.5\],"projection":"perspective","target":\[0,0,0\]},"grid":{"axisColors":{"x":"\#ef4444","y":"\#22c55e","z":"\#3b82f6"},"divisions":10,"gridColor":"\#e5e7eb","showAxes":true,"showLabels":true,"size":10,"visible":true},"id":"1f5abaee-474d-47f5-91aa-67247cab881d","metadata":{"alt\_text":"A near-top-down view of twelve nested dark elliptical contour lines of f(x,y) = x^2/2 + y^2, overlaid with a flat grid of gradient arrows colored from purple to yellow by strength; every arrow meets its ellipse at a right angle and points outward, away from the center. A translucent bowl-shaped surface of the same function is present but hidden.","created\_at":"2026-07-07T00:00:00.000Z","description":"Workbook scene: 12-level contour plot of f(x,y) = x^2/2 + y^2 at z = 0 with the gradient field (x, 2y, 0) flattened into the same plane; a hidden translucent surface of f is unhidden in the last phase to confirm arrows point uphill.","tags":\["workbook","calc3","gradient","contours","vector-field"\],"updated\_at":"2026-07-07T00:00:00.000Z"},"objects":\[{"expression":"x^2/2 + y^2","id":"75e945f0-19db-4624-b1cf-9b3afab760d0","kind":"contour-plot","label":{"text":"level curves of f","visible":true},"levels":12,"style":{"color":"\#0f172a","dash":\[\],"lineWidth":2},"visible":true,"xDomain":\[-3,3\],"yDomain":\[-3,3\],"zOffset":0},{"density":9,"id":"d38b487a-4c50-4fdc-8b61-5c506e88b877","kind":"vector-field","label":{"text":"grad f","visible":true},"pExpr":"x","qExpr":"2\*y","rExpr":"0","style":{"arrowScale":36,"colorByMagnitude":true,"colormap":"viridis","fixedColor":"\#f59e0b"},"visible":true,"xDomain":\[-3,3\],"yDomain":\[-3,3\],"zDomain":\[-0.05,0.05\]},{"expression":"x^2/2 + y^2","id":"cf46bca6-5918-463a-9cd3-41d2f84563f1","kind":"explicit-surface","label":{"text":"z = x^2/2 + y^2","visible":true},"resolution":96,"style":{"colormap":"viridis","doubleSided":true,"opacity":0.35,"wireframe":false,"wireframeColor":"\#000000"},"visible":false,"xDomain":\[-3,3\],"yDomain":\[-3,3\]}\],"title":"Arrows always cross at right angles","version":1} A near-top-down view of twelve nested elliptical level curves of #math.equation(block: false, alt: "f open parenthesis x , y close parenthesis equals x squared / 2 plus y squared")[$f ( x , y ) = x^(2) / 2 + y^(2)$] (the outermost run off the edge of the window), under a flat carpet of gradient arrows colored from purple (weak) to yellow (strong) โ€” color, not length, carries the gradient's magnitude here. A translucent surface of #math.equation(block: false, alt: "f")[$f$] hides in the object list until the last exploration step. {"expression":"x^2/2 + y^2","variables":\["x","y"\]} The gradient of the same #math.equation(block: false, alt: "f")[$f$] the figure contours, computed from the formula rather than read off the arrows. The #math.equation(block: false, alt: "y")[$y$]-component is twice the #math.equation(block: false, alt: "x")[$x$]-component's coefficient, which is why the ellipses are wider than they are tall and why the arrows lean the way they do. === Explore + Pick any arrow away from the center and look at the ellipse it sits on. At what angle does the arrow cross its curve? Check five more arrows in different parts of the map. Do you find a single exception? + Every arrow points away from the center โ€” the bottom of the bowl. Do the arrows turn yellow (strong) where the ellipses pack tightly, or where they spread apart? Say why, using the map-reading skill that opened Chapter 3: crowded contours mean steep ground. + The gradient here is #math.equation(block: false, alt: "โˆ‡ f equals open parenthesis x , 2 y close parenthesis")[$โˆ‡ f = ( x , 2 y )$]. Before zooming in, predict: at #math.equation(block: false, alt: "open parenthesis 3 , 1.5 close parenthesis")[$( 3 , 1.5 )$], which compass direction does the arrow point, and how many times stronger is it than the arrow at #math.equation(block: false, alt: "open parenthesis 1.5 , 0.75 close parenthesis")[$( 1.5 , 0.75 )$]? + Zoom in and check โ€” the field samples every #math.equation(block: false, alt: "0.75")[$0.75$] units, so an arrow sits exactly at each of those points. Direction should match, and the stronger arrow should sit visibly further toward yellow. + Both points of step 3 lie on one ray from the origin. Will #emph[every] arrow on that ray point the same way? Will that hold on the #math.equation(block: false, alt: "y")[$y$]-axis too? Zoom out and check both. + Reveal the hidden surface with its eye toggle and orbit down to a low side view. Confirm the whole point: at every sampled point, the arrow on the map aims in the direction the surface climbs. === Why the crossing is always square Walk #emph[along] a level curve and, by definition, the value of #math.equation(block: false, alt: "f")[$f$] does not change: the directional derivative along the curve's tangent #math.equation(block: false, alt: "๐“")[$๐“$] is zero. But #math.equation(block: false, alt: "D sub ๐“ f equals โˆ‡ f times ๐“")[$D_(๐“) f = โˆ‡ f ยท ๐“$], so the gradient has no component along the level curve at all โ€” it is purely normal to it. Perpendicularity is not a coincidence of this bowl; it is the dot product doing its job. And since equally spaced levels crowd where the surface is steep, the strongest (yellowest) arrows live exactly where the ellipses bunch: the map's spacing and the arrows' color are two readouts of the same number, #math.equation(block: false, alt: "โ€– โˆ‡ f โ€–")[$โ€– โˆ‡ f โ€–$]. #examplebox("Example 1")[Auditing two arrows by hand][ For #math.equation(block: false, alt: "f open parenthesis x , y close parenthesis equals x squared / 2 plus y squared")[$f ( x , y ) = x^(2) / 2 + y^(2)$], compute the gradient at #math.equation(block: false, alt: "open parenthesis 3 , 1.5 close parenthesis")[$( 3 , 1.5 )$] and at #math.equation(block: false, alt: "open parenthesis 1.5 , 0.75 close parenthesis")[$( 1.5 , 0.75 )$], compare their directions and strengths, and verify that the first is perpendicular to the level curve through its point. From #math.equation(block: false, alt: "f sub x equals x")[$f_(x) = x$] and #math.equation(block: false, alt: "f sub y equals 2 y")[$f_(y) = 2 y$]: #math.equation(block: true, alt: "โˆ‡ f open parenthesis 3 , 1.5 close parenthesis equals open parenthesis 3 , 3 close parenthesis , โˆ‡ f open parenthesis 1.5 , 0.75 close parenthesis equals open parenthesis 1.5 , 1.5 close parenthesis .")[$โˆ‡ f ( 3 , 1.5 ) = ( 3 , 3 ) , #h(2em) โˆ‡ f ( 1.5 , 0.75 ) = ( 1.5 , 1.5 ) .$] Both point along #math.equation(block: false, alt: "open parenthesis 1 , 1 close parenthesis")[$( 1 , 1 )$] โ€” diagonally outward at #math.equation(block: false, alt: "45")[$45$] degrees, matching step 5's ray observation โ€” with magnitudes #math.equation(block: false, alt: "3 the square root of 2")[$3 sqrt(2)$] and #math.equation(block: false, alt: "1.5 the square root of 2")[$1.5 sqrt(2)$]: the outer arrow is exactly twice as strong, hence visibly yellower. For perpendicularity, the level curve through #math.equation(block: false, alt: "open parenthesis 3 , 1.5 close parenthesis")[$( 3 , 1.5 )$] is #math.equation(block: false, alt: "x squared / 2 plus y squared equals 27 / 4")[$x^(2) / 2 + y^(2) = 27 / 4$]. Differentiating implicitly, #math.equation(block: false, alt: "x plus 2 y y prime equals 0")[$x + 2 y y^(โ€ฒ) = 0$], so at #math.equation(block: false, alt: "open parenthesis 3 , 1.5 close parenthesis")[$( 3 , 1.5 )$] the slope is #math.equation(block: false, alt: "y prime equals minus 3 / 3 equals minus 1")[$y^(โ€ฒ) = โˆ’ 3 / 3 = โˆ’ 1$] and the tangent direction is #math.equation(block: false, alt: "open parenthesis 1 , minus 1 close parenthesis")[$( 1 , โˆ’ 1 )$]. Then #math.equation(block: true, alt: "โˆ‡ f times ๐“ equals open parenthesis 3 , 3 close parenthesis times open parenthesis 1 , minus 1 close parenthesis equals 3 minus 3 equals 0 :")[$โˆ‡ f ยท ๐“ = ( 3 , 3 ) ยท ( 1 , โˆ’ 1 ) = 3 โˆ’ 3 = 0 :$] the arrow crosses its ellipse at a right angle, just as every arrow on the map does. ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ The gradient is a compass needle for uphill and a speedometer in one: direction of fastest increase, magnitude the rate, always square to the level curve. When an optimization argument later says "move against the gradient," it is quoting this picture. ]