# A dozen minima for a parabola This section uses these packages: ```{julia} using SymPy using Plots ``` ---- In the March 2003 issue of the College Mathematics Journal, Leon M Hall posed 12 questions related to the following figure: ```{julia} #| echo: false f(x) = x^2 fp(x) = 2x a₀ = 7/8 q₀ = -a₀ - 1/(2a₀) tangent(x) = f(a₀) + fp(a₀) * (x - a₀) normal(x) = f(a₀) - (1 / fp(a₀)) * (x - a₀) function make_plot(a₀=7/8, q₀=-a₀ - 1/2a₀) plt = plot(; xlim=(-2,2), ylim=(-1, (1.5)^2), xticks=nothing, yticks=nothing, aspect_ratio=:equal, border=:none, legend=false) f(x) = x^2 fp(x) = 2x plot!(f, -1.5, 1.5) plot!(zero) tl = x -> f(a₀) + fp(a₀) * (x-a₀) nl = x -> f(a₀) - 1/(fp(a₀)) * (x-a₀) plot!(tl, -0.02, 1.6; linecolor=:black) plot!(nl, -1.6, 1; linecolor=:black) # add in right triangle scatter!([a₀, q₀], f.([a₀, q₀]), markersize=5) Δ = 0.01 annotate!([(a₀ + Δ, nl(a₀+Δ), "P", :bottom), (q₀ - Δ, nl(q₀-Δ), "Q", :top)]) plt end make_plot() ``` The figure shows $f(x) = x^2$, the tangent line at $(a, f(a))$ (for $a > 0$), and the *normal* line at $(a, f(a))$. The questions all involve finding the value $a$ which minimizes a related quantity. We set up some variables to work symbolically: ```{julia} @syms a::positive x::real f(x) = x^2 fp(x) = 2x m = fp(a) mᴵ = - 1/m tl = f(a) + m * (x - a) nl = f(a) + mᴵ * (x - a) zs = solve(f(x) ~ nl, x) q = only(filter(!=(a), zs)) ``` ---- The first question is simply: > 1a. The $y$ coordinate of $Q$ ```{julia} #| echo: false let p = make_plot() plot!(p, [q₀,q₀], [0,normal(q₀)], linewidth=5) end ``` The value is $f(q)$ ```{julia} yvalue = f(q) ``` To minimize we solve for critical points: ```{julia} cps = solve(diff(yvalue, a), a) ``` The lone critical point must be at a minimum. (Given the geometry of the problem, as $a$ goes to $\infty$ the height does too, and as $a$ goes to $0$ the height will also go to $\infty$. This can also be seen analytically, as $q = -a - 1/(2a)$ which goes to $-\infty$ when $a$ heads to $0$ or $\infty$.) ::: {.callout-note} ## We hide the code In the remaining examples we don't show the code by default. ::: ---- > 1b. The length of the line segment $PQ$ ```{julia} #| echo: false p = make_plot() plot!([q₀, a₀], [f(q₀), f(a₀)], linewidth=5) ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" lseg = sqrt((f(a) - f(q))^2 + (a - q)^2); ``` ---- > 2a. The horizontal distance between $P$ and $Q$ ```{julia} #| echo: false p = make_plot() plot!([q₀, a₀], [f(a₀), f(a₀)], linewidth=5) ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" hd = a - q; ``` ---- > 2b. The area of the parabolic segment ```{julia} #| echo: false p = make_plot() xs′ = range(q₀, a₀, 50) xs = vcat(xs′, reverse(xs′), first(xs′)) ys = vcat(f.(xs′), normal.(reverse(xs′)), f(first(xs′))) plot!(xs, ys, fill=(:green, 0.25, 0)) ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" A = simplify(integrate(nl - f(x), (x, q, a))); ``` ---- > 2c. The volume of the rotated solid formed by revolving the parabolic segment around the vertical line $k$ units to the right of $P$ or to the left of $Q$ where $k > 0$. ```{julia} #| code-fold: true #| code-summary: "Show the code" @syms k::nonnegative V = simplify(integrate(PI * (nl - f(x) - k)^2, (x, q, a))); ``` ---- > 3. The $y$ coordinate of the centroid of the parabolic segment ```{julia} #| echo: false p = make_plot() scatter!(p, [-1/(4a₀)], [1], marker=(10, :diamond)) p ``` We warm up with the $x$ coordinate, given by: ```{julia} xₘ = integrate(x * (nl - f(x)), (x, q, a)) / A simplify(xₘ) ``` a fact noted by the author. ```{julia} #| code-fold: true #| code-summary: "Show the code" yₘ = integrate( (1//2) * (nl^2 - f(x)^2), (x, q, a)) / A yₘ = simplify(yₘ); ``` ---- > 4. The length of the arc of the parabola between $P$ and $Q$ ```{julia} #| echo: false p = make_plot() xs = range(q₀, a₀, 100) plot!(xs, f.(xs), linewidth=5) p ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" L = integrate(sqrt(1 + fp(x)^2), (x, q, a)); ``` ---- > 5. The $y$ coordinate of the midpoint ofthe line segment $PQ$ ```{julia} #| echo: false p = make_plot() mid = a₀/2 + q₀/2 vline!([mid]) scatter!([mid], [normal(mid)], markersize=5) p ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" mp = nl(x => (a + q)/2); ``` ---- > 6. The area of the trapezoid bound by the normal line, the $x$-axis, and the vertical lines through $P$ and $Q$. ```{julia} #| echo: false p = make_plot() plot!([q₀, a₀, a₀, q₀, q₀], [0, 0, f(a₀), f(q₀), 0]; fill=(:green, 0.25, 0)) p ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" trap = 1//2 * (f(q) + f(a)) * (a - q); ``` ---- > 7. The area bounded by the parabola and the $x$ axis and the vertical lines through $P$ and $Q$ ```{julia} #| echo: false p = make_plot() ts = range(q₀, a₀, 100) xs = vcat(ts, a₀, q₀, q₀) ys = vcat(f.(ts), 0, 0, f(q₀)) plot!(xs, ys, fill=(:green, 0.25, 0)) p ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" pa = integrate(x^2, (x, q, a)); ``` ---- > 8. The area of the surface formed by revolving the arc of the parabola between $P$ and $Q$ around the vertical line through $P$ ```{julia} #| echo: false let using SplitApplyCombine S(x, θ) = (a₀ - (a₀-x)*cos(θ), (a₀-x)*sin(θ), f(x)) xs = range(q₀, a₀, 50) θs = range(0, 2pi, 50) surface(SplitApplyCombine.invert(S.(xs,θs'))...) end ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" # use parametric and 2π ∫ u(t) √(u'(t)^2 + v'(t)^2) dt uu(x) = a - x vv(x) = f(uu(x)) SA = 2PI * integrate(uu(x) * sqrt(diff(uu(x),x)^2 + diff(vv(x),x)^2), (x, q, a)); ``` ---- > 9. The height of the parabolic segment (i.e. the distance between the normal line and the tangent line to the parabola that is parallel to the normal line) ```{julia} #| echo: false # distance point to a line # > solve(diff(x^2,x) ~ -1/fp(a), x) # mean value theorem # -1/(4*a) b₀ = -1/(4a₀) # mean value approach # f(b0) + fp(a0)*(x-b0) = f(a0) - 1/fp(a0)*(x-a0) x₀ = a₀/2 - 1/(8*a₀) make_plot() plot!(x -> f(b₀) + (-1/fp(a₀))*(x - b₀), -1, 1/2) plot!([b₀,x₀], [f(b₀), normal(x₀)]; linewidth=5) ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" # find b through mean value theorem, # then solve for point of intersection b = only(solve(diff(f(x),x) ~ -1/fp(a), x)) b′ = only(solve(f(b) + fp(a)*(x-b) ~ nl, x)) segment_height = sqrt((b-b′)^2 + (f(b) - nl(x=>b′))^2); ``` ---- > 10. The volume of the solid formed by revolving the parabolic segment around the $x$-axis ```{julia} #| echo: false let using SplitApplyCombine S(x,θ) = (x, ((f(a₀) - 1/fp(a₀)*(x - a₀)) .* (sin(θ), cos(θ)))...) xs = range(q₀, a₀, 50) θs = range(0, 2pi, 50) surface(SplitApplyCombine.invert(S.(xs,θs'))...) end ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" Vₓ = integrate(pi * (nl^2 - f(x)^2), (x, q, a)); ``` ---- > 11. The area of the triangle bound by the normal line, the vertical line through $Q$ and the $x$-axis ```{julia} #| echo: false make_plot() # solve 0 = y0 + m * (x-x0) --> x0 - y0/m p₀ = a₀ - f(a₀) / (-1/fp(a₀)) xlims!((-2, p₀ + 0.2)) plot!([p₀,q₀,q₀,p₀], [0,f(q₀),0,0]; fill=(:green, 0.25,0)) ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" triangle = 1/2 * f(q) * (a - f(a)/(-1/fp(a)) - q); ``` ---- > 12. The area of the quadrilateral bound by the normal line, the tangent line, the vertical line through $Q$ and the $x$-axis ```{julia} #| echo: false make_plot() plot!([a₀,q₀,q₀,a₀-f(a₀)/fp(a₀),a₀], [f(a₀), f(q₀), 0, 0,f(a₀)], fill=(:green, 0.25, 0)) ``` ```{julia} #| code-fold: true #| code-summary: "Show the code" # @syms x[1:4], y[1:4] # v1, v2, v3 = [[x[i]-x[1],y[i]-y[1], 0] for i in 2:4] # area = 1//2 * last(cross(v3,v2) + cross(v2, v1)) # 1/2 area of parallelogram # print(simplify(area)) # -(x₁ - x₂)*(y₁ - y₃)/2 + (x₁ - x₃)*(y₁ - y₂)/2 - (x₁ - x₃)*(y₁ - y₄)/2 + (x₁ - x₄)*(y₁ - y₃)/2 tl₀ = a - f(a) / fp(a) x₁,x₂,x₃,x₄ = (a,q,q,tl₀) y₁, y₂, y₃, y₄ = (f(a), f(q), 0, 0) quadrilateral = -(x₁ - x₂)*(y₁ - y₃)/2 + (x₁ - x₃)*(y₁ - y₂)/2 - (x₁ - x₃)*(y₁ - y₄)/2 + (x₁ - x₄)*(y₁ - y₃)/2; ``` ---- The answers appear here in sorted order, some given as approximate floating point values: ```{julia} article_answers = (1/(2sqrt(2)), 1/2, sqrt(3/10), 0.558480, 0.564641, 0.569723, 0.574646, 1/sqrt(3), 1/8^(1/4), 1/6^(1/4), .644004, 1/sqrt(2)) ``` ```{julia} #| echo: false # check problems = ("1a"=>yvalue, "1b"=>lseg, "1c"=>hd, "2a" => A, "2b" => V, "3" => yₘ, "4" => L, "5" => mp, "6" => trap, "7" => pa, "8" => SA, "9" => segment_height, "10" => Vₓ, "11" => triangle, "12" => quadrilateral ) ≈ₒ(a,b) = isapprox(a, b; atol=1e-5, rtol=sqrt(eps())) ∂ = Differential(a) solutions = [k => only(solve(∂(p) ~ 0, a)) for (k,p) in problems] [(sol=k, correct=(any(isapprox.(s, article_answers; atol=1e-5)))) for (k,s) ∈ solutions] nothing ```