This commit is contained in:
jverzani
2025-07-23 08:05:43 -04:00
parent 31ce21c8ad
commit c3a94878f3
50 changed files with 3711 additions and 1385 deletions

View File

@@ -230,13 +230,22 @@ function secant_line_tangent_line_graph(n)
xs = range(0, stop=pi, length=50)
fig_size=(800, 600)
plt = plot(f, 0, pi, legend=false, size=fig_size,
line=(2,),
axis=([],false),
plt = plot(;
xaxis=([], false),
yaxis=([], false),
framestyle=:origin,
legend=false,
ylims=(-.1,1.5)
)
plot!([0, 1.1* pi],[0,0], line=(3, :black))
plot!([0, 0], [0,2*1], line=(3, :black))
plot!(f, 0, pi/2; line=(:black, 2))
plot!(f, pi/2, pi/2 + pi/5; line=(:black, 2, 1/4))
plot!(f, pi/2 + pi/5, pi; line=(:black, 2))
plot!(0.1 .+ [0,0],[-.1, 1.5]; line=(:gray,1), arrow=true, side=:head)
plot!([-0.2, 3.4], [.1, .1]; line=(:gray, 1), arrow=true, side=:head)
plot!(plt, xs, f(c) .+ cos(c)*(xs .- c), color=:orange)
plot!(plt, xs, f(c) .+ m*(xs .- c), color=:black)
@@ -244,8 +253,10 @@ function secant_line_tangent_line_graph(n)
plot!(plt, [c, c+h, c+h], [f(c), f(c), f(c+h)], color=:gray30)
annotate!(plt, [(c+h/2, f(c), text("h", :top)),
(c + h + .05, (f(c) + f(c + h))/2, text("f(c+h) - f(c)", :left))
annotate!(plt, [(c+h/2, f(c), text(L"h", :top)),
(c + h + .05, (f(c) + f(c + h))/2, text(L"f(c+h) - f(c)", :left)),
])
plt
@@ -258,7 +269,7 @@ The slope of each secant line represents the *average* rate of change between $c
n = 5
n = 6
anim = @animate for i=0:n
secant_line_tangent_line_graph(i)
end
@@ -279,11 +290,59 @@ $$
We will define the tangent line at $(c, f(c))$ to be the line through the point with the slope from the limit above - provided that limit exists. Informally, the tangent line is the line through the point that best approximates the function.
::: {#fig-tangent_line_approx_graph}
```{julia}
#| echo: false
gr()
let
function make_plot(Δ)
f(x) = 1 + sin(x-c)
df(x) = cos(x-c)
plt = plot(;
#xaxis=([], false),
yaxis=([], false),
aspect_ratio=:equal,
legend=false,
)
c = 1
xticks!([c-Δ, c, c+Δ], [latexstring("c-$Δ"), L"c", latexstring("c-$Δ")])
y₀ = f(c) - 2/3 * Δ
tl(x) = f(c) + df(c) * (x-c)
plot!(f, c - Δ, c + Δ; line=(:black, 2))
plot!(tl, c - Δ, c + Δ; line=(:red, 2))
plot!([c,c], [tl(c-Δ), f(c)]; line=(:gray, :dash, 1))
#plot!([c-1.1*Δ, c+1.1*Δ], y₀ .+ [0,0]; line=(:gray, 1), arrow=true)
current()
end
ps = make_plot.((1.5, 1.0, 0.5, 0.1))
plot(ps...)
end
```
Illustration that the tangent line is the best linear approximation *near* $c$.
:::
```{julia}
#| echo: false
plotly()
nothing
```
```{julia}
#| hold: true
#| echo: false
#| cache: true
#| eval: false
gr()
function line_approx_fn_graph(n)
f(x) = sin(x)

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -50,7 +50,7 @@ A parallel definition with $a < b$ implying $f(a) > f(b)$ would be used for a *s
We can try and prove these properties for a function algebraically we'll see both are related to the zeros of some function. However, before proceeding to that it is usually helpful to get an idea of where the answer is using exploratory graphs.
We will use a helper function, `plotif(f, g, a, b)` that plots the function `f` over `[a,b]` highlighting the regions in the domain when `g` is non-negative. Such a function is defined for us in the accompanying `CalculusWithJulia` package, which has been previously been loaded.
We will use a helper function, `plotif(f, g, a, b)` that plots the function `f` over `[a,b]` highlighting the regions in the domain when `g` is non-negative. Such a function is defined for us in the accompanying `CalculusWithJulia` package, which has been previously loaded.
To see where a function is positive, we simply pass the function object in for *both* `f` and `g` above. For example, let's look at where $f(x) = \sin(x)$ is positive:
@@ -475,22 +475,22 @@ Let's look at the function $x^2 \cdot e^{-x}$ for positive $x$. A quick graph sh
```{julia}
h(x) = x^2 * exp(-x)
plotif(h, h'', 0, 8)
g(x) = x^2 * exp(-x)
plotif(g, g'', 0, 8)
```
From the graph, we would expect that the second derivative - which is continuous - would have two zeros on $[0,8]$:
```{julia}
ips = find_zeros(h'', 0, 8)
ips = find_zeros(g'', 0, 8)
```
As well, between the zeros we should have the sign pattern `+`, `-`, and `+`, as we verify:
```{julia}
sign_chart(h'', 0, 8)
sign_chart(g'', 0, 8)
```
### Second derivative test
@@ -744,6 +744,90 @@ choices=[
answ = 3
radioq(choices, answ)
```
###### Question
The function
$$
f(x) =
\begin{cases}
\frac{x}{2} + x^2 \sin(\frac{\pi}{x}) & x \neq 0\\
0 & x = 0
\end{cases}
$$
is graphed below over $[-1/3, 1/3]$.
```{julia}
#| echo: false
plt = let
gr()
empty_style = (xaxis=([], false),
yaxis=([], false),
framestyle=:origin,
legend=false)
axis_style = (arrow=true, side=:head, line=(:gray, 1))
## f'(0) > 0 but not increasing
f(x) = x/2 + x^2 * sinpi(1/x)
g(x) = x/2 - x^2
a, b = -1/3, 1/3
xs = range(a, b, 10_000)
ys = f.(xs)
y0,y1 = extrema(ys)
plot(; empty_style..., aspect_ratio=:equal)
plot!([a,b],[0,0]; axis_style...)
plot!([0,0], [y0,y1]; axis_style...)
plot!(xs, f.(xs); line=(:black, 1))
plot!(xs, x -> x/2 + x^2; line=(:gray, 1, :dot))
plot!(xs, x -> x/2 - x^2; line=(:gray, 1, :dot))
plot!(xs, x -> x/2; line=(:gray, 1))
a1 = (1/4 + 1/5)/2
a2 = -(1*1/3 + 4*1/4)/5
annotate!([
(a1, g(a1), text(L"\frac{x}{2} - x^2", 10, :top)),
(a1, f(a1), text(L"\frac{x}{2} + x^2", 10, :bottom)),
(-1/6, f(1/6), text(L"\frac{x}{2} + x^2\sin(\frac{\pi}{x})", 10, :bottom))
])
plot!([-1/6, -1/13.5], [f(1/6), f(-1/13.5)]; axis_style...)
end
plt
```
```{julia}
#| echo: false
plotly()
nothing
```
This function has a derivative at $0$ that is *positive*
```{julia}
f(x) = x == 0 ? 0 : x/2 + x^2 * sinpi(1/x)
@syms h
limit((f(0+h) - f(0))/h, h=>0; dir="+-")
```
Is the function increasing **around** $0$?
(The derivative away from $0$ is given by:
```{julia}
@syms x
diff(f(x), x)
```
```{julia}
#| echo: false
choices = ["Yes", "No"]
answer = 1
buttonq(choices, answer; explanation=raw"""
The slope of the tangent line away from $0$ oscillates from positive to negative at every rational number of the form $1/n$ due to the $\cos(\pi/x)$ term, so it is neither going just up or down around $0$. (This example comes from @Angenent.)
""")
```
###### Question
@@ -779,21 +863,30 @@ Consider the following figure of a graph of $f$:
```{julia}
#| echo: false
ex(x) = x * tanh(exp(x))
a, b = -5, 1
plot(ex, a, b, legend=false,
axis=([], false),
color = :royalblue
)
plot!([a-.1, b+.1], [0,0], line=(3, :black))
let
gr()
ex(x) = x * tanh(exp(x))
a, b = -5, 1
plot(ex, a, b, legend=false,
axis=([], false),
line=(:black, 2)
)
plot!([a-.1, b+.1], [0,0], line=(:gray,1), arrow=true, side=:head)
zs = find_zeros(ex, (a, b))
cps = find_zeros(ex', (a, b))
ips = find_zeros(ex'', (a, b))
zs = find_zeros(ex, (a, b))
cps = find_zeros(ex', (a, b))
ips = find_zeros(ex'', (a, b))
scatter!(zs, ex.(zs), marker=(5, "black", :circle))
scatter!(cps, ex.(cps), marker=(5, "forestgreen", :diamond))
scatter!(ips, ex.(ips), marker=(5, :brown3, :star5))
scatter!(zs, ex.(zs), fill=(:black,), marker=(8, :circle))
scatter!(cps, ex.(cps), fill=(:green,), marker=(8, :diamond))
scatter!(ips, ex.(ips), fill=(:brown3,), marker=(8,:star5))
end
```
```{julia}
#| echo: false
plotly()
nothing
```
The black circle denotes what?

View File

@@ -93,6 +93,42 @@ In general though, we may not be able to solve for $y$ in terms of $x$. What the
The idea is to *assume* that $y$ is representable by some function of $x$. This makes sense, moving on the curve from $(x,y)$ to some nearby point, means changing $x$ will cause some change in $y$. This assumption is only made *locally* - basically meaning a complicated graph is reduced to just a small, well-behaved, section of its graph.
::: {#fig-well-behaved-section}
```{julia}
#| echo: false
let
gr()
a = 1
k = 2
F(x,y) = a * (x + a)*(x^2 + y^2) - k*x^2
xs = range(-3/2, 3/2, 100)
ys = range(-2, 2, 100)
contour(xs, ys, F; levels=[0],
axis=([], nothing),
line=(:black, 1),
framestyle=:none, legend=false)
x₀, y₀ = 3/4, -0.2834733547569205
m = (-a^2*x₀ - 3*a*x₀^2/2 - a*y₀^2/2 + k*x₀)/(a*(a + x₀)*y₀)
plot!(x -> y₀ + m*(x - x₀), x₀-0.5, x₀ + 0.5; line=(:gray, 2))
plot!(x -> -x*sqrt(-(a^2 + a*x - k)/(a*(a + x))), -1/8,0.99;
line=(:black,4))
scatter!([x₀], [y₀]; marker=(:circle,5,:yellow))
end
```
```{julia}
#| echo: false
plotly()
nothing
```
Graph of an equation with a well behaved section emphasized. The tangent line can be found by finding a formula for this well behaved section and differentiating *or* by implicit differentiation simply by assuming a form for the implicit function.
:::
With this assumption, asking what $dy/dx$ is has an obvious meaning - what is the slope of the tangent line to the graph at $(x,y)$. (The assumption eliminates the question of what a tangent line would mean when a graph self intersects.)
@@ -120,7 +156,7 @@ This says the slope of the tangent line depends on the point $(x,y)$ through the
As a check, we compare to what we would have found had we solved for $y= \sqrt{1 - x^2}$ (for $(x,y)$ with $y \geq 0$). We would have found: $dy/dx = 1/2 \cdot 1/\sqrt{1 - x^2} \cdot (-2x)$. Which can be simplified to $-x/y$. This should show that the method above - assuming $y$ is a function of $x$ and differentiating - is not only more general, but can even be easier.
The name - *implicit differentiation* - comes from the assumption that $y$ is implicitly defined in terms of $x$. According to the [Implicit Function Theorem](http://en.wikipedia.org/wiki/Implicit_function_theorem) the above method will work provided the curve has sufficient smoothness near the point $(x,y)$.
The name - *implicit differentiation* - comes from the assumption that $y$ is implicitly defined in terms of $x$. According to the [Implicit Function Theorem](http://en.wikipedia.org/wiki/Implicit_function_theorem) the above method will work provided the curve has sufficient smoothness near the point $(x,y)$. (Continuously differentiable and non vanishing derivative in $y$.)
##### Examples
@@ -140,10 +176,16 @@ For $a = 2, b=1$ we have the graph:
#| hold: true
a, b = 2, 1
f(x,y) = x^2*y + a * b * y - a^2 * x
implicit_plot(f)
implicit_plot(f; legend=false)
x₀, y₀ = 0, 0
m = (a^2 - 2x₀*y₀) / (a*b + x₀^2)
plot!(x -> y₀ + m*(x - x₀), -1, 1)
```
We can see that at each point in the viewing window the tangent line exists due to the smoothness of the curve. Moreover, at a point $(x,y)$ the tangent will have slope $dy/dx$ satisfying:
To the plot we added a tangent line at $(0,0)$.
We can see that at each point in the viewing window the tangent line exists due to the smoothness of the curve. To find the slope of the tangent line at a point $(x,y)$ the tangent line will have slope $dy/dx$ satisfying:
$$
@@ -177,7 +219,7 @@ A graph for $a=3$ shows why it has the name it does:
#| hold: true
a = 3
f(x,y) = x^4 - a^2*(x^2 - y^2)
implicit_plot(f)
implicit_plot(f; xticks=-5:5)
```
The tangent line at $(x,y)$ will have slope, $dy/dx$ satisfying:
@@ -341,7 +383,7 @@ The next step is solve for $dy/dx$ - the lone answer to the linear equation - wh
```{julia}
dydx = diff(u(x), x)
ex3 = solve(ex2, dydx)[1] # pull out lone answer with [1] indexing
ex3 = only(solve(ex2, dydx)) # pull out the only answer
```
As this represents an answer in terms of `u(x)`, we replace that term with the original variable:
@@ -369,9 +411,9 @@ Let $a = b = c = d = 1$, then $(1,4)$ is a point on the curve. We can draw a tan
```{julia}
H = ex(a=>1, b=>1, c=>1, d=>1)
x0, y0 = 1, 4
𝒎 = dydx₁(x=>1, y=>4, a=>1, b=>1, c=>1, d=>1)
m = dydx₁(x=>1, y=>4, a=>1, b=>1, c=>1, d=>1)
implicit_plot(lambdify(H); xlims=(-5,5), ylims=(-5,5), legend=false)
plot!(y0 + 𝒎 * (x-x0))
plot!(y0 + m * (x-x0))
```
Basically this includes all the same steps as if done "by hand." Some effort could have been saved in plotting, had values for the parameters been substituted initially, but not doing so shows their dependence in the derivative.
@@ -379,7 +421,7 @@ Basically this includes all the same steps as if done "by hand." Some effort cou
:::{.callout-warning}
## Warning
The use of `lambdify(H)` is needed to turn the symbolic expression, `H`, into a function.
The use of `lambdify(H)` is needed to turn the symbolic expression, `H`, into a function for plotting purposes.
:::
@@ -517,15 +559,9 @@ This could have been made easier, had we leveraged the result of the previous ex
#### Example: from physics
Many problems are best done with implicit derivatives. A video showing such a problem along with how to do it analytically is [here](http://ocw.mit.edu/courses/mathematics/18-01sc-single-variable-calculus-fall-2010/unit-2-applications-of-differentiation/part-b-optimization-related-rates-and-newtons-method/session-32-ring-on-a-string/).
This video starts with a simple question:
> If you have a rope and heavy ring, where will the ring position itself due to gravity?
This problem illustrates one best done with implicit derivatives. A video showing this problem along with how to do it analytically is [here](http://ocw.mit.edu/courses/mathematics/18-01sc-single-variable-calculus-fall-2010/unit-2-applications-of-differentiation/part-b-optimization-related-rates-and-newtons-method/session-32-ring-on-a-string/).
Well, suppose you hold the rope in two places, which we can take to be $(0,0)$ and $(a,b)$. Then let $(x,y)$ be all the possible positions of the ring that hold the rope taught. Then we have this picture:
@@ -534,19 +570,41 @@ Well, suppose you hold the rope in two places, which we can take to be $(0,0)$ a
```{julia}
#| hold: true
#| echo: false
let
gr()
P = (4,1)
Q = (1, -3)
scatter([0,4], [0,1], legend=false, xaxis=nothing, yaxis=nothing)
plot!([0,1,4],[0,-3,1])
𝑎, 𝑏= .05, .25
plot(;
axis=([],false),
legend=false)
scatter!([0,4], [0,1])
plot!([0,1,4],[0,-3,1]; line=(:black,2))
a, b = .05, .25
ts = range(0, 2pi, length=100)
plot!(1 .+ 𝑎*sin.(ts), -3 .+ 𝑏*cos.(ts), color=:gold)
annotate!((4-0.3,1,"(a,b)"))
plot!([0,1,1],[0,0,-3], color=:gray, alpha=0.25)
plot!([1,1,4],[0,1,1], color=:gray, alpha=0.25)
Δ = 0.15
annotate!([(1/2, 0-Δ, "x"), (5/2, 1 - Δ, "a-x"), (1-Δ, -1, "|y|"), (1+Δ, -1, "b-y")])
plot!(1 .+ a*sin.(ts), -3 .+ b*cos.(ts), line=(:gold,2))
plot!([0,1,1],[0,0,-3], color=:gray, alpha=0.75)
plot!([1,1,4],[0,1,1], color=:gray, alpha=0.75)
Δ = 0.05
annotate!([
(0,0, text(L"(0,0)",:bottom)),
(4,1, text(L"(a,b)",:bottom)),
(1/2, 0, text(L"x",:top)),
(5/2, 1, text(L"a-x", :top)),
(1, -1, text(L"|y|",:right)),
(1+Δ, -1, text(L"b-y",:left)),
(1+2a, -3, text(L"(x,y)",:left))
])
current()
end
```
```{julia}
#| echo: false
plotly()
nothing
```
Since the length of the rope does not change, we must have for any admissible $(x,y)$ that:

View File

@@ -28,17 +28,17 @@ We know this is $1$ using a bound from geometry, but might also guess this is on
$$
\sin(x) = x - \sin(\xi)x^2/2, \quad 0 < \xi < x.
\sin(x) = x - \sin(\xi)\frac{x^2}{2}, \quad 0 < \xi < x.
$$
This would yield:
$$
\lim_{x \rightarrow 0} \frac{\sin(x)}{x} = \lim_{x\rightarrow 0} \frac{x -\sin(\xi) x^2/2}{x} = \lim_{x\rightarrow 0} 1 - \sin(\xi) \cdot x/2 = 1.
\lim_{x \rightarrow 0} \frac{\sin(x)}{x} = \lim_{x\rightarrow 0} \frac{x -\sin(\xi) \frac{x^2}{2}}{x} = \lim_{x\rightarrow 0} 1 - \sin(\xi) \cdot \frac{x}{2} = 1.
$$
This is because we know $\sin(\xi) x/2$ has a limit of $0$, when $|\xi| \leq |x|$.
This is because we know $\sin(\xi) \frac{x}{2}$ has a limit of $0$, when $|\xi| \leq |x|$.
That doesn't look any easier, as we worried about the error term, but if just mentally replaced $\sin(x)$ with $x$ - which it basically is near $0$ - then we can see that the limit should be the same as $x/x$ which we know is $1$ without thinking.
@@ -384,10 +384,10 @@ the first equality by L'Hospital's rule, as the second limit exists.
Indeterminate forms of the type $0 \cdot \infty$, $0^0$, $\infty^\infty$, $\infty - \infty$ can be re-expressed to be in the form $0/0$ or $\infty/\infty$ and then L'Hospital's theorem can be applied.
###### Example: rewriting $0 \cdot \infty$
##### Example: rewriting $0 \cdot \infty$
What is the limit $x \log(x)$ as $x \rightarrow 0+$? The form is $0\cdot \infty$, rewriting, we see this is just:
What is the limit of $x \log(x)$ as $x \rightarrow 0+$? The form is $0\cdot \infty$, rewriting, we see this is just:
$$
@@ -401,10 +401,10 @@ $$
\lim_{x \rightarrow 0+}\frac{1/x}{-1/x^2} = \lim_{x \rightarrow 0+} -x = 0.
$$
###### Example: rewriting $0^0$
##### Example: rewriting $0^0$
What is the limit $x^x$ as $x \rightarrow 0+$? The expression is of the form $0^0$, which is indeterminate. (Even though floating point math defines the value as $1$.) We can rewrite this by taking a log:
What is the limit of $x^x$ as $x \rightarrow 0+$? The expression is of the form $0^0$, which is indeterminate. (Even though floating point math defines the value as $1$.) We can rewrite this by taking a log:
$$

View File

@@ -186,25 +186,45 @@ In each of these cases, a more complicated non-linear function is well approxim
#| echo: false
#| label: fig-tangent-dy-dx
#| fig-cap: "Graph with tangent line layered on"
f(x) = sin(x)
a, b = -1/4, pi/2
let
gr()
f(x) = sin(x)
a, b = -1/4, pi/2
p = plot(f, a, b, legend=false,
line=(3, :royalblue),
axis=([], false)
);
p = plot(f, a, b, legend=false,
line=(3, :royalblue),
axis=([], false)
);
plot!(p, x->x, a, b);
plot!(p, [0,1,1], [0, 0, 1], color=:brown);
plot!(p, x->x, a, b);
plot!(p, [0,1,1], [0, 0, 1], color=:brown);
plot!(p, [1,1], [0, sin(1)], color=:green, linewidth=4);
plot!(p, [1,1], [0, sin(1)], color=:green, linewidth=4);
scatter!([0], [0], marker=(5, :mediumorchid3))
annotate!(p, [(0, f(0), text("(c,f(c))", :bottom,:right))])
annotate!(p, collect(zip([1/2, 1+.075, 1/2-1/8],
[.05, sin(1)/2, .75],
["Δx", "Δy", "m=dy/dx"])));
x₀ = 1.15
δ = 0.1
plot!(p, [x₀,x₀,1], [sin(1)/2-δ,0,0], line=(:black, 1, :dash), arrow=true)
plot!(p, [x₀,x₀,1], [sin(1)/2+δ,1, 1], line=(:black, 1, :dash), arrow=true)
plot!(p, [1/2 - 0.8δ, 0], [-δ, -δ]*3/4, line=(:black, 1, :dash), arrow=true)
plot!(p, [1/2 + 0.8δ, 1], [-δ, -δ]*3/4, line=(:black, 1, :dash), arrow=true)
scatter!([0], [0], marker=(5, :mediumorchid3))
annotate!(p, [
(0, f(0), text(L"(c, f(c))", :bottom, :right)),
(1/2, 0, text(L"\Delta x", :bottom)),
(1/2, 0, text(L"dx", :top)),
(1-0.02, sin(1)/2, text(L"Δ y", :right)),
(x₀, sin(1)/2, text(L"dy")),
(2/3, 2/3, text(L"m = \frac{dy}{dx} \approx \frac{\Delta y}{\Delta x}",
:bottom, rotation=33)) # why 33 and not 45?
])
p
end
```
```{julia}
#| echo: false
plotly()
nothing
```
The plot in @fig-tangent-dy-dx shows a tangent line with slope $dy/dx$ and the actual change in $y$, $\Delta y$, for some specified $\Delta x$ at a point $(c,f(c))$. The small gap above the sine curve is the error were the value of the sine approximated using the drawn tangent line. We can see that approximating the value of $\Delta y = \sin(c+\Delta x) - \sin(c)$ with the often easier to compute $(dy/dx) \cdot \Delta x = f'(c)\Delta x$ - for small enough values of $\Delta x$ - is not going to be too far off provided $\Delta x$ is not too large.
@@ -480,7 +500,8 @@ To see formally why the remainder is as it is, we recall the mean value theorem
$$
\text{error} = h(x) - h(0) = (g(x) - g(0)) \frac{h'(e)}{g'(e)} = x^2 \cdot \frac{1}{2} \cdot \frac{f'(e) - f'(0)}{e} =
\text{error} = h(x) - h(0) = (g(x) - g(0)) \frac{h'(e)}{g'(e)} =
(x^2 - 0) \cdot \frac{f'(e) - f'(0)}{2e} =
x^2 \cdot \frac{1}{2} \cdot f''(\xi).
$$
@@ -551,7 +572,8 @@ Is it a coincidence that a basic algebraic operation with tangent lines approxim
$$
\begin{align*}
f(x) \cdot g(x) &= [f(c) + f'(c)(x-c) + \mathcal{O}((x-c)^2)] \cdot [g(c) + g'(c)(x-c) + \mathcal{O}((x-c)^2)]\\
&=[f(c) + f'(c)(x-c)] \cdot [g(c) + g'(c)(x-c)] + (f(c) + f'(c)(x-c)) \cdot \mathcal{O}((x-c)^2) + (g(c) + g'(c)(x-c)) \cdot \mathcal{O}((x-c)^2) + [\mathcal{O}((x-c)^2)]^2\\
&=[f(c) + f'(c)(x-c)] \cdot [g(c) + g'(c)(x-c)] \\
&+ (f(c) + f'(c)(x-c)) \cdot \mathcal{O}((x-c)^2) + (g(c) + g'(c)(x-c)) \cdot \mathcal{O}((x-c)^2) + [\mathcal{O}((x-c)^2)]^2\\
&= [f(c) + f'(c)(x-c)] \cdot [g(c) + g'(c)(x-c)] + \mathcal{O}((x-c)^2)\\
&= f(c) \cdot g(c) + [f'(c)\cdot g(c) + f(c)\cdot g'(c)] \cdot (x-c) + [f'(c)\cdot g'(c) \cdot (x-c)^2 + \mathcal{O}((x-c)^2)] \\
&= f(c) \cdot g(c) + [f'(c)\cdot g(c) + f(c)\cdot g'(c)] \cdot (x-c) + \mathcal{O}((x-c)^2)
@@ -630,7 +652,7 @@ Automatic differentiation (forward mode) essentially uses this technique. A "dua
```{julia}
Dual(0, 1)
x = Dual(0, 1)
```
Then what is $x$? It should reflect both $(\sin(0), \cos(0))$ the latter being the derivative of $\sin$. We can see this is *almost* what is computed behind the scenes through:
@@ -638,11 +660,13 @@ Then what is $x$? It should reflect both $(\sin(0), \cos(0))$ the latter being t
```{julia}
#| hold: true
x = Dual(0, 1)
@code_lowered sin(x)
```
This output of `@code_lowered` can be confusing, but this simple case needn't be. Working from the end we see an assignment to a variable named `%3` of `Dual(%6, %12)`. The value of `%6` is `sin(x)` where `x` is the value `0` above. The value of `%12` is `cos(x)` *times* the value `1` above (the `xp`), which reflects the *chain* rule being used. (The derivative of `sin(u)` is `cos(u)*du`.) So this dual number encodes both the function value at `0` and the derivative of the function at `0`.
This output of `@code_lowered` can be confusing, but this simple case needn't be, as we know what to look for: we need to evaluate `sin` at `1` and carry along the derivative `cos(x)` **times** the derivative at `x`.
The `sin` is computed in `%6` and is passed to `Dual` in `%13` as the first arguments. The `cos` is computed in `%11` and then *multiplied* in `%` by `xp`, which holds the derivative information about `x`. This is passed as the second argument to `Dual` in `%13`.
Similarly, we can see what happens to `log(x)` at `1` (encoded by `Dual(1,1)`):
@@ -654,14 +678,15 @@ x = Dual(1, 1)
@code_lowered log(x)
```
We can see the derivative again reflects the chain rule, it being given by `1/x * xp` where `xp` acts like `dx` (from assignments `%9` and `%8`). Comparing the two outputs, we see only the assignment to `%9` differs, it reflecting the derivative of the function.
We again see `log(x)` being evaluated in line `%6`. The derivative evaluated at `x` is done in line `%11` and this is multiplied by `xp` in line `%12`.
## Curvature
The curvature of a function will be a topic in a later section on differentiable vector calculus, but the concept of linearization can be used to give an earlier introduction.
The tangent line linearizes the function, it begin the best linear approximation to the graph of the function at the point. The slope of the tangent line is the limit of the slopes of different secant lines. Consider now, the orthogonal concept, the *normal line* at a point. This is a line perpendicular to the tangent line that goes through the point on the curve.
The tangent line linearizes the function, it being the best linear approximation to the graph of the function at the point. The slope of the tangent line is the limit of the slopes of different secant lines. Consider now, the orthogonal concept, the *normal line* at a point. This is a line perpendicular to the tangent line that goes through the point on the curve.
At a point $(c,f(c))$ the slope of the normal line is $-1/f'(c)$.
@@ -692,6 +717,7 @@ Call $R$ the intersection point of the two normal lines:
#| echo: false
using Roots
let
gr()
f(x) = x^4
fp(x) = 4x^3
c = 1/4
@@ -706,12 +732,17 @@ let
Rx = find_zero(x -> nlc(x) - nlch(x), (-10, 10))
scatter!([c,c+h], f.([c, c+h]))
scatter!([Rx], [nlc(Rx)])
annotate!([(c, f(c), "(c,f(c))",:top),
(c+h, f(c+h), "(c+h, f(c+h))",:bottom),
(Rx, nlc(Rx), "R",:left)])
annotate!([(c, f(c), L"(c,f(c))",:top),
(c+h, f(c+h), L"(c+h, f(c+h))",:bottom),
(Rx, nlc(Rx), L"R",:left)])
end
```
```{julia}
#| echo: false
plotly()
nothing
```
What happens to $R$ as $h \rightarrow 0$?
@@ -760,6 +791,7 @@ This formula for $r$ is known as the radius of curvature of $f$ -- the radius of
```{julia}
#| echo: false
let
gr()
f(x) = x^4
fp(x) = 4x^3
fpp(x) = 12x^2
@@ -779,8 +811,8 @@ let
scatter!([c], f.([c]))
scatter!([Rx], [nlc(Rx)])
annotate!([(c, f(c), "(c,f(c))",:top),
(Rx, nlc(Rx), "R",:left)])
annotate!([(c, f(c), L"(c,f(c))",:top),
(Rx, nlc(Rx), L"R",:left)])
Delta = pi/10
@@ -801,6 +833,12 @@ let
end
```
```{julia}
#| echo: false
plotly()
nothing
```
## Questions

View File

@@ -277,6 +277,13 @@ For $f$ differentiable on $(a,b)$ and continuous on $[a,b]$, if $f(a)=f(b)$, the
:::
::: {#fig-l-hospital-144}
![Figure from L'Hospital's calculus book](figures/lhopital-144.png)
Figure from L'Hospital's calculus book showing Rolle's theorem where $c=E$ in the labeling.
:::
This modest observation opens the door to many relationships between a function and its derivative, as it ties the two together in one statement.
@@ -323,46 +330,71 @@ The mean value theorem is a direct generalization of Rolle's theorem.
::: {.callout-note icon=false}
## Mean value theorem
Let $f(x)$ be differentiable on $(a,b)$ and continuous on $[a,b]$. Then there exists a value $c$ in $(a,b)$ where $f'(c) = (f(b) - f(a)) / (b - a)$.
Let $f(x)$ be differentiable on $(a,b)$ and continuous on $[a,b]$. Then there exists a value $c$ in $(a,b)$ where
$$
f'(c) = (f(b) - f(a)) / (b - a).
$$
:::
This says for any secant line between $a < b$ there will be a parallel tangent line at some $c$ with $a < c < b$ (all provided $f$ is differentiable on $(a,b)$ and continuous on $[a,b]$).
Figure @fig-mean-value-theorem illustrates the theorem. The blue line is the secant line. A parallel line tangent to the graph is guaranteed by the mean value theorem. In this figure, there are two such lines, rendered using brown.
@fig-mean-value-theorem illustrates the theorem. The secant line between $a$ and $b$ is dashed. For this function there are two values of $c$ where the slope of the tangent line is seen to be the same as the slope of this secant line. At least one is guaranteed by the theorem.
```{julia}
#| hold: true
#| echo: false
#| label: fig-mean-value-theorem
f(x) = x^3 - x
a, b = -2, 1.75
m = (f(b) - f(a)) / (b-a)
cps = find_zeros(x -> f'(x) - m, a, b)
let
# mean value theorem
gr()
f(x) = x^3 -4x^2 + 3x - 1
a, b = -3/4, 3+3/4
plot(; axis=([], nothing),
legend=false,
xlims=(-1.1,4),
framestyle=:none)
y₀ = 0.3 + f(-1)
p = plot(f, a-0.75, b+1,
color=:mediumorchid3,
linewidth=3, legend=false,
axis=([],false),
)
plot!(f, -1, 4; line=(:black, 2))
plot!([-1.1, 4], y₀*[1,1]; line=(:black, 1), arrow=true, head=:top)
p,q = (a,f(a)), (b, f(b))
scatter!([p,q]; marker=(:circle, 4, :red))
plot!([p,q]; line=(:gray, 2, :dash))
m = (f(b) - f(a))/(b-a)
c₁, c₂ = find_zeros(x -> f'(x) - m, (a,b))
Δ = 2/3
for c ∈ (c₁, c₂)
plot!(tangent(f,c), c-Δ, c+Δ; line=(:gray, 2))
plot!([(c, y₀), (c, f(c))]; line=(:gray, 1, :dash))
end
for c ∈ (a,b)
plot!([(c, y₀), (c, f(c))]; line=(:gray, 1))
end
annotate!([
(a, y₀, text(L"a", :top)),
(b, y₀, text(L"b", :top)),
(c₁, y₀, text(L"c_1", :top)),
(c₂, y₀, text(L"c_2", :top)),
])
current()
plot!(x -> f(a) + m*(x-a), a-1, b+1, linewidth=5, color=:royalblue)
scatter!([a,b], [f(a), f(b)])
annotate!([(a, f(a), text("a", :bottom)),
(b, f(b), text("b", :bottom))])
for cp in cps
plot!(x -> f(cp) + f'(cp)*(x-cp), a-1, b+1, color=:brown3)
end
```
scatter!(cps, f.(cps))
subsscripts = collect("₀₁₂₃₄₅₆₇₈₉")
annotate!([(cp, f(cp), text("c"*subsscripts[i], :bottom)) for (i,cp) ∈ enumerate(cps)])
p
```{julia}
#| echo: false
plotly()
nothing
```
Like Rolle's theorem this is a guarantee that something exists, not a recipe to find it. In fact, the mean value theorem is just Rolle's theorem applied to:
@@ -506,7 +538,7 @@ function parametric_fns_graph(n)
xlim=(-1.1,1.1), ylim=(-pi/2-.1, pi/2+.1))
scatter!(plt, [f(ts[end])], [g(ts[end])], color=:orange, markersize=5)
val = @sprintf("% 0.2f", ts[end])
annotate!(plt, [(0, 1, "t = $val")])
annotate!(plt, [(0, 1, L"t = %$val")])
end
caption = L"""

View File

@@ -315,10 +315,10 @@ One way to think about this is the difference between `x` and the next largest f
For the specific example, `abs(b-a) <= 2eps(m)` means that the gap between `a` and `b` is essentially 2 floating point values from the $x$ value with the smallest $f(x)$ value.
For bracketing methods that is about as good as you can get. However, once floating values are understood, the absolute best you can get for a bracketing interval would be
For bracketing methods that is about as good as you can get. However, once floating point values are understood, the absolute best you can get for a bracketing interval would be
* along the way, a value `f(c)` is found which is *exactly* `0.0`
* along the way, a value `f(c)` is found which evaluates *exactly* to `0.0`
* the endpoints of the bracketing interval are *adjacent* floating point values, meaning the interval can not be bisected and `f` changes sign between the two values.
@@ -334,6 +334,8 @@ chandrapatla(fu, -9, 1, λ3)
Here the issue is `abs(b-a)` is tiny (of the order `1e-119`) but `eps(m)` is even smaller.
> For checking if $x_n \approx x_{n+1}$ both a relative and absolute error should be used unless something else is known.
For non-bracketing methods, like Newton's method or the secant method, different criteria are useful. There may not be a bracketing interval for `f` (for example `f(x) = (x-1)^2`) so the second criteria above might need to be restated in terms of the last two iterates, $x_n$ and $x_{n-1}$. Calling this difference $\Delta = |x_n - x_{n-1}|$, we might stop if $\Delta$ is small enough. As there are scenarios where this can happen, but the function is not at a zero, a check on the size of $f$ is needed.
@@ -347,7 +349,7 @@ First if `f(x_n)` is `0.0` then it makes sense to call `x_n` an *exact zero* of
However, there may never be a value with `f(x_n)` exactly `0.0`. (The value of `sin(1pi)` is not zero, for example, as `1pi` is an approximation to $\pi$, as well the `sin` of values adjacent to `float(pi)` do not produce `0.0` exactly.)
Suppose `x_n` is the closest floating number to $\alpha$, the zero. Then the relative rounding error, $($ `x_n` $- \alpha)/\alpha$, will be a value $\delta$ with $\delta$ less than `eps()`.
Suppose `x_n` is the closest floating point number to $\alpha$, the zero. Then the relative rounding error, $($ `x_n` $- \alpha)/\alpha$, will be a value $\delta$ with $\delta$ less than `eps()`.
How far then can `f(x_n)` be from $0 = f(\alpha)$?
@@ -364,10 +366,11 @@ $$
f(x_n) \approx f(\alpha) + f'(\alpha) \cdot (\alpha\delta) = f'(\alpha) \cdot \alpha \delta
$$
So we should consider `f(x_n)` an *approximate zero* when it is on the scale of $f'(\alpha) \cdot \alpha \delta$.
So we should consider `f(x_n)` an *approximate zero* when it is on the scale of $f'(\alpha) \cdot \alpha \delta$. That $\alpha$ factor means we consider a *relative* tolerance for `f`.
> For checking if $f(x_n) \approx 0$ both a relative and absolute error should be used--the relative error involving the size of $x_n$.
That $\alpha$ factor means we consider a *relative* tolerance for `f`. Also important when `x_n` is close to `0`, is the need for an *absolute* tolerance, one not dependent on the size of `x`. So a good condition to check if `f(x_n)` is small is
A good condition to check if `f(x_n)` is small is
`abs(f(x_n)) <= abs(x_n) * rtol + atol`, or `abs(f(x_n)) <= max(abs(x_n) * rtol, atol)`
@@ -396,7 +399,7 @@ It is not uncommon to assign `rtol` to have a value like `sqrt(eps())` to accoun
In Part III of @doi:10.1137/1.9781611977165 we find language of numerical analysis useful to formally describe the zero-finding problem. Key concepts are errors, conditioning, and stability. These give some theoretical justification for the tolerances above.
Abstractly a *problem* is a mapping, $F$, from a domain $X$ of data to a range $Y$ of solutions. Both $X$ and $Y$ have a sense of distance given by a *norm*. A norm is a generalization of the absolute value and gives quantitative meaning to terms like small and large.
Abstractly a *problem* is a mapping, $F$, from a domain $X$ of data to a range $Y$ of solutions. Both $X$ and $Y$ have a sense of distance given by a *norm*. A norm (denoted with $\lVert\cdot\rVert$) is a generalization of the absolute value and gives quantitative meaning to terms like small and large.
> A *well-conditioned* problem is one with the property that all small perturbations of $x$ lead to only small changes in $F(x)$.
@@ -435,7 +438,7 @@ $$
\tilde{F}(x) = F(\tilde{x})
$$
for some $\tilde{x}$ with $\lVert\tilde{x} - x\rVert/\lVert x\rVert$ is small.
for some $\tilde{x}$ where $\lVert\tilde{x} - x\rVert/\lVert x\rVert$ is small.
> "A backward stable algorithm gives exactly the right answer to nearly the right question."

View File

@@ -413,7 +413,7 @@ To machine tolerance the answer is a zero, even though the exact answer is irrat
The first example by Newton of applying the method to a non-polynomial function was solving an equation from astronomy: $x - e \sin(x) = M$, where $e$ is an eccentric anomaly and $M$ a mean anomaly. Newton used polynomial approximations for the trigonometric functions, here we can solve directly.
Let $e = 1/2$ and $M = 3/4$. With $f(x) = x - e\sin(x) - M$ then $f'(x) = 1 - e cos(x)$. Starting at 1, Newton's method for 3 steps becomes:
Let $e = 1/2$ and $M = 3/4$. With $f(x) = x - e\sin(x) - M$ then $f'(x) = 1 - e \cos(x)$. Starting at 1, Newton's method for 3 steps becomes:
```{julia}
ec, M = 0.5, 0.75
@@ -490,7 +490,7 @@ $$
x_{i+1} = x_i - (1/x_i - q)/(-1/x_i^2) = -qx^2_i + 2x_i.
$$
Now for $q$ in the interval $[1/2, 1]$ we want to get a *good* initial guess. Here is a claim. We can use $x_0=48/17 - 32/17 \cdot q$. Let's check graphically that this is a reasonable initial approximation to $1/q$:
Now for $q$ in the interval $[1/2, 1]$ we want to get a *good* initial guess. Here is a claim: we can use $x_0=48/17 - 32/17 \cdot q$. Let's check graphically that this is a reasonable initial approximation to $1/q$:
```{julia}
@@ -865,7 +865,7 @@ The function $f(x) = x^{20} - 1$ has two bad behaviours for Newton's
method: for $x < 1$ the derivative is nearly $0$ and for $x>1$ the
second derivative is very big. In this illustration, we have an
initial guess of $x_0=8/9$. As the tangent line is fairly flat, the
next approximation is far away, $x_1 = 1.313\dots$. As this guess
next approximation is far away, $x_1 = 1.313\dots$. As this guess
is much bigger than $1$, the ratio $f(x)/f'(x) \approx
x^{20}/(20x^{19}) = x/20$, so $x_i - f(x_i)/f'(x_i) \approx (19/20)x_i$
yielding slow, linear convergence until $f''(x_i)$ is moderate. For

View File

@@ -70,7 +70,7 @@ function perimeter_area_graphic_graph(n)
size=fig_size,
xlim=(0,10), ylim=(0,10))
scatter!(plt, [w], [h], color=:orange, markersize=5)
annotate!(plt, [(w/2, h/2, "Area=$(round(w*h,digits=1))")])
annotate!(plt, [(w/2, h/2, L"Area$=\; %$(round(w*h,digits=1))$")])
plt
end
@@ -79,7 +79,7 @@ caption = """
Some possible rectangles that satisfy the constraint on the perimeter and their area.
"""
n = 6
n = 5
anim = @animate for i=1:n
perimeter_area_graphic_graph(i-1)
end
@@ -187,8 +187,11 @@ ts = range(0, stop=pi, length=50)
x1,y1 = 4, 4.85840
x2,y2 = 3, 6.1438
delta = 4
p = plot(delta .+ x1*[0, 1,1,0], y1*[0,0,1,1], linetype=:polygon, fillcolor=:blue, legend=false)
plot!(p, x2*[0, 1,1,0], y2*[0,0,1,1], linetype=:polygon, fillcolor=:blue)
p = plot(delta .+ x1*[0, 1,1,0], y1*[0,0,1,1];
linetype=:polygon, fillcolor=:blue, legend=false,
aspect_ratio=:equal)
plot!(p, x2*[0, 1,1,0], y2*[0,0,1,1];
linetype=:polygon, fillcolor=:blue)
plot!(p, delta .+ x1/2 .+ x1/2*cos.(ts), y1.+x1/2*sin.(ts), linetype=:polygon, fillcolor=:red)
plot!(p, x2/2 .+ x2/2*cos.(ts), y2 .+ x2/2*sin.(ts), linetype=:polygon, fillcolor=:red)
@@ -308,7 +311,7 @@ A₀ = w₀ * h₀ + pi * (w₀/2)^2 / 2
Perim = 2*h₀ + w₀ + pi * w₀/2
h₁ = solve(Perim - 20, h₀)[1]
A₁ = A₀(h₀ => h₁)
w₁ = solve(diff(A₁,w₀), w₀)[1]
w₁ = solve(diff(A₁,w₀) ~ 0, w₀)[1]
```
We know that `w₀` is the maximum in this example from our previous work. We shall see soon, that just knowing that the second derivative is negative at `w₀` would suffice to know this. Here we check that condition:
@@ -392,14 +395,29 @@ The figure shows a ladder of length $l_1 + l_2$ that got stuck - it was too long
```{julia}
#| hold: true
#| echo: false
p = plot([0, 0, 15], [15, 0, 0], color=:blue, legend=false)
plot!(p, [5, 5, 15], [15, 8, 8], color=:blue)
plot!(p, [0,14.53402874075368], [12.1954981558864, 0], linewidth=3)
plot!(p, [0,5], [8,8], color=:orange)
plot!(p, [5,5], [0,8], color=:orange)
annotate!(p, [(13, 1/2, "θ"),
(2.5, 11, "l₂"), (10, 5, "l₁"), (2.5, 7.0, "l₂ ⋅ cos(θ)"),
(5.1, 4, "l₁ ⋅ sin(θ)")])
let
gr()
p = plot([0, 0, 15], [15, 0, 0],
xticks = [0,5, 15],
yticks = [0,8, 12],
line=(:blue, 2),
legend=false)
plot!(p, [5, 5, 15], [15, 8, 8]; line=(:blue,2))
plot!(p, [0,14.53402874075368], [12.1954981558864, 0], linewidth=3)
plot!(p, [0,5], [8,8], color=:orange)
plot!(p, [5,5], [0,8], color=:orange)
annotate!(p, [(13, 1/2, L"\theta"),
(2.5, 11, L"l_2"),
(10, 5, L"l_1"),
(2.5, 7.0, L"l_2 \cos(\theta)"),
(5.1, 4, text(L"l_1 \sin(\theta)", :top,rotation=90))])
end
```
```{julia}
#| echo: false
plotly()
nothing
```
We approach this problem in reverse. It is easy to see when a ladder is too long. It gets stuck at some angle $\theta$. So for each $\theta$ we find that ladder length that is just too long. Then we find the minimum length of all these ladders that are too long. If a ladder is this length or more it will get stuck for some angle. However, if it is less than this length it will not get stuck. So to maximize a ladder length, we minimize a different function. Neat.
@@ -834,10 +852,12 @@ A rancher with $10$ meters of fence wishes to make a pen adjacent to an existing
```{julia}
#| hold: true
#| echo: false
p = plot(; legend=false, aspect_ratio=:equal, axis=nothing, border=:none)
p = plot(; legend=false, aspect_ratio=:equal, axis=nothing, border=:none)
plot!([0,10, 10, 0, 0], [0,0,10,10,0]; linewidth=3)
plot!(p, [10,14,14,10], [2, 2, 8,8]; linewidth = 1)
annotate!(p, [(15, 5, "x"), (12,1, "y")])
annotate!(p, [(14-0.1, 5, text("x", :right)), (12,2, text("y",:bottom))])
p
```
@@ -1353,7 +1373,12 @@ p = 1/2
x = a/p
plot!(plt, [0, b*(1+p), 0, 0], [0, 0, a+x, 0])
plot!(plt, [b,b,0,0],[0,a,a,0])
annotate!(plt, [(b/2,0, "b"), (0,a/2,"a"), (0,a+x/2,"x"), (b+b*p/2,0,"bp")])
annotate!(plt, [
(b/2,0, text("b",:top)),
(0,a/2, text("a",:right)),
(0,a+x/2, text("x",:right)),
(b+b*p/2,0, text("bp",:top))
])
plt
```

View File

@@ -18,7 +18,7 @@ using SymPy
---
Related rates problems involve two (or more) unknown quantities that are related through an equation. As the two variables depend on each other, also so do their rates - change with respect to some variable which is often time, though exactly how remains to be discovered. Hence the name "related rates."
Related rates problems involve two (or more) unknown quantities that are related through an equation. As the two variables depend on each other, also so do their rates - change with respect to some variable which is often time. Exactly how remains to be discovered. Hence the name "related rates."
#### Examples
@@ -27,7 +27,7 @@ Related rates problems involve two (or more) unknown quantities that are related
The following is a typical "book" problem:
> A screen saver displays the outline of a $3$ cm by $2$ cm rectangle and then expands the rectangle in such a way that the $2$ cm side is expanding at the rate of $4$ cm/sec and the proportions of the rectangle never change. How fast is the area of the rectangle increasing when its dimensions are $12$ cm by $8$ cm? [Source.](http://oregonstate.edu/instruct/mth251/cq/Stage9/Practice/ratesProblems.html)
> A *vintage* screen saver displays the outline of a $3$ cm by $2$ cm rectangle and then expands the rectangle in such a way that the $2$ cm side is expanding at the rate of $4$ cm/sec and the proportions of the rectangle never change. How fast is the area of the rectangle increasing when its dimensions are $12$ cm by $8$ cm? [Source.](http://oregonstate.edu/instruct/mth251/cq/Stage9/Practice/ratesProblems.html)
@@ -125,7 +125,7 @@ w(t) = 2 + 4*t
```{julia}
h(t) = 3/2 * w(t)
h(t) = 3 * w(t) / 2
```
This means again that area depends on $t$ through this formula:
@@ -198,6 +198,50 @@ A ladder, with length $l$, is leaning against a wall. We parameterize this probl
If the ladder starts to slip away at the base, but remains in contact with the wall, express the rate of change of $h$ with respect to $t$ in terms of $db/dt$.
```{julia}
#| echo: false
let
gr()
l = 12
b = 6
h = sqrt(l^2 - b^2)
plot(;
axis=([],false),
legend=false,
aspect_ratio=:equal)
P,Q = (0,h),(b,0)
w = 0.2
S = Shape([-w,0,0,-w],[0,0,h+1,h+1])
plot!(S; fillstyle=:/, fillcolor=:gray80, fillalpha=0.5)
R = Shape([-w,b+2,b+2,-w],[-w,-w,0,0])
plot!(R, fill=(:gray, 0.25))
plot!([P,Q]; line=(:black, 2))
scatter!([P,Q])
b = b + 3/2
h = sqrt(l^2 - b^2)
plot!([b,b],[0,0]; arrow=true, side=:head, line=(:blue, 3))
plot!([0,0], [h,h]; arrow=true, side=:head, line=(:blue, 3))
annotate!([
(b,-w,text(L"(b(t),0)",:top)),
(-w, h, text(L"(0,h(t))", :bottom, rotation=90)),
(b/2, h/2, text(L"L", rotation = -atand(h,b), :bottom))
])
current()
end
```
```{julia}
#| echo: false
plotly()
nothing
```
We have from implicitly differentiating in $t$ the equation $l^2 = h^2 + b^2$, noting that $l$ is a constant, that:
@@ -236,7 +280,7 @@ As $b$ goes to $l$, $h$ goes to $0$, so $b/h$ blows up. Unless $db/dt$ goes to $
:::{.callout-note}
## Note
Often, this problem is presented with $db/dt$ having a constant rate. In this case, the ladder problem defies physics, as $dh/dt$ eventually is faster than the speed of light as $h \rightarrow 0+$. In practice, were $db/dt$ kept at a constant, the ladder would necessarily come away from the wall. The trajectory would follow that of a tractrix were there no gravity to account for.
Often, this problem is presented with $db/dt$ having a constant rate. In this case, the ladder problem defies physics, as $dh/dt$ eventually is faster than the speed of light as $h \rightarrow 0+$. In practice, were $db/dt$ kept at a constant, the ladder would necessarily come away from the wall.
:::
@@ -247,12 +291,15 @@ Often, this problem is presented with $db/dt$ having a constant rate. In this ca
```{julia}
#| hold: true
#| echo: false
#| eval: false
caption = "A man and woman walk towards the light."
imgfile = "figures/long-shadow-noir.png"
ImageFile(:derivatives, imgfile, caption)
```
![A man and woman walk towards the light](./figures/long-shadow-noir.png)
Shadows are a staple of film noir. In the photo, suppose a man and a woman walk towards a street light. As they approach the light the length of their shadow changes.
@@ -340,7 +387,7 @@ This can be solved for the unknown: $dx/dt = 50/20$.
A batter hits a ball toward third base at $75$ ft/sec and runs toward first base at a rate of $24$ ft/sec. At what rate does the distance between the ball and the batter change when $2$ seconds have passed?
We will answer this with `SymPy`. First we create some symbols for the movement of the ball towards third base, `b(t)`, the runner toward first base, `r(t)`, and the two velocities. We use symbolic functions for the movements, as we will be differentiating them in time:
We will answer this symbolically. First we create some symbols for the movement of the ball towards third base, `b(t)`, the runner toward first base, `r(t)`, and the two velocities. We use symbolic functions for the movements, as we will be differentiating them in time:
```{julia}

View File

@@ -42,12 +42,14 @@ gr()
taylor(f, x, c, n) = series(f, x, c, n+1).removeO()
function make_taylor_plot(u, a, b, k)
k = 2k
plot(u, a, b, title="plot of T_$k", linewidth=5, legend=false, size=fig_size, ylim=(-2,2.5))
if k == 1
plot!(zero, range(a, stop=b, length=100))
else
plot!(taylor(u, x, 0, k), range(a, stop=b, length=100))
end
plot(u, a, b;
title = L"plot of $T_{%$k}$",
line = (:black, 3),
legend = false,
size = fig_size,
ylim = (-2,2.5))
fn = k == 1 ? zero : taylor(u, x, 0, k)
plot!(fn, range(a, stop=b, length=100); line=(:red,2))
end
@@ -76,7 +78,7 @@ ImageFile(imgfile, caption)
## The secant line and the tangent line
We approach this general problem **much** more indirectly than is needed. We introduce notations that are attributed to Newton and proceed from there. By leveraging `SymPy` we avoid tedious computations and *hopefully* gain some insight.
Heads up: we approach this general problem **much** more indirectly than is needed by introducing notations that are attributed to Newton and proceed from there. By leveraging `SymPy` we avoid tedious computations and *hopefully* gain some insight.
Suppose $f(x)$ is a function which is defined in a neighborhood of $c$ and has as many continuous derivatives as we care to take at $c$.
@@ -102,7 +104,10 @@ $$
tl(x) = f(c) + f'(c) \cdot(x - c).
$$
The key is the term multiplying $(x-c)$ for the secant line this is an approximation to the related term for the tangent line. That is, the secant line approximates the tangent line, which is the linear function that best approximates the function at the point $(c, f(c))$. This is quantified by the *mean value theorem* which states under our assumptions on $f(x)$ that there exists some $\xi$ between $x$ and $c$ for which:
The key is the term multiplying $(x-c)$ -- for the secant line this is an approximation to the related term for the tangent line. That is, the secant line approximates the tangent line, which is the linear function that best approximates the function at the point $(c, f(c))$.
This is quantified by the *mean value theorem* which states under our assumptions on $f(x)$ that there exists some $\xi$ between $x$ and $c$ for which:
$$
@@ -189,7 +194,7 @@ function divided_differences(f, x, xs...)
end
```
In the following, by adding a `getindex` method, we enable the `[]` notation of Newton to work with symbolic functions, like `u()` defined below, which is used in place of $f$:
In the following--even though it is *type piracy*--by adding a `getindex` method, we enable the `[]` notation of Newton to work with symbolic functions, like `u()` defined below, which is used in place of $f$:
```{julia}
@@ -199,48 +204,38 @@ Base.getindex(u::SymFunction, xs...) = divided_differences(u, xs...)
ex = u[c, c+h]
```
We can take a limit and see the familiar (yet differently represented) value of $u'(c)$:
A limit as $h\rightarrow 0$ would show a value of $u'(c)$.
```{julia}
limit(ex, h => 0)
```
The choice of points is flexible. Here we use $c-h$ and $c+h$:
```{julia}
limit(u[c-h, c+h], h=>0)
```
Now, let's look at:
```{julia}
ex₂ = u[c, c+h, c+2h]
simplify(ex₂)
```
Not so bad after simplification. The limit shows this to be an approximation to the second derivative divided by $2$:
If multiply by $2$ and simplify, a discrete approximation for the second derivative--the second order forward [difference equation](http://tinyurl.com/n4235xy)--is seen:
```{julia}
limit(ex₂, h => 0)
simplify(2ex₂)
```
(The expression is, up to a divisor of $2$, the second order forward [difference equation](http://tinyurl.com/n4235xy), a well-known approximation to $f''$.)
This relationship between higher-order divided differences and higher-order derivatives generalizes. This is expressed in this [theorem](http://tinyurl.com/zjogv83):
> Suppose $m=x_0 < x_1 < x_2 < \dots < x_n=M$ are distinct points. If $f$ has $n$ continuous derivatives then there exists a value $\xi$, where $m < \xi < M$, satisfying:
:::{.callout-note}
## Mean value theorem for Divided differences
Suppose $m=x_0 < x_1 < x_2 < \dots < x_n=M$ are distinct points. If $f$ has $n$ continuous derivatives then there exists a value $\xi$, where $m < \xi < M$, satisfying:
$$
f[x_0, x_1, \dots, x_n] = \frac{1}{n!} \cdot f^{(n)}(\xi).
$$
:::
This immediately applies to the above, where we parameterized by $h$: $x_0=c, x_1=c+h, x_2 = c+2h$. For then, as $h$ goes to $0$, it must be that $m, M \rightarrow c$, and so the limit of the divided differences must converge to $(1/2!) \cdot f^{(2)}(c)$, as $f^{(2)}(\xi)$ converges to $f^{(2)}(c)$.
@@ -496,16 +491,20 @@ f[x_0] &+ f[x_0,x_1] \cdot (x - x_0) + f[x_0, x_1, x_2] \cdot (x - x_0)\cdot(x-x
$$
and taking $x_i = c + i\cdot h$, for a given $n$, we have in the limit as $h > 0$ goes to zero that coefficients of this polynomial converge to the coefficients of the *Taylor Polynomial of degree n*:
and taking $x_i = c + i\cdot h$, for a given $n$, we have in the limit as $h > 0$ goes to zero that coefficients of this polynomial converge:
:::{.callout-note}
## Taylor polynomial of degree $n$
Suppose $f(x)$ has $n+1$ derivatives (continuous on $c$ and $x$), then
$$
f(c) + f'(c)\cdot(x-c) + \frac{f''(c)}{2!}(x-c)^2 + \cdots + \frac{f^{(n)}(c)}{n!} (x-c)^n.
T_n(x) = f(c) + f'(c)\cdot(x-c) + \frac{f''(c)}{2!}(x-c)^2 + \cdots + \frac{f^{(n)}(c)}{n!} (x-c)^n,
$$
This polynomial will be the best approximation of degree $n$ or less to the function $f$, near $c$. The error will be given - again by an application of the Cauchy mean value theorem:
will be the best approximation of degree $n$ or less to $f$, near $c$.
The error will be given - again by an application of the Cauchy mean value theorem:
$$
@@ -513,9 +512,10 @@ $$
$$
for some $\xi$ between $c$ and $x$.
:::
The Taylor polynomial for $f$ about $c$ of degree $n$ can be computed by taking $n$ derivatives. For such a task, the computer is very helpful. In `SymPy` the `series` function will compute the Taylor polynomial for a given $n$. For example, here is the series expansion to 10 terms of the function $\log(1+x)$ about $c=0$:
The Taylor polynomial for $f$ about $c$ of degree $n$ can be computed by taking $n$ derivatives. For such a task, the computer is very helpful. In `SymPy` the `series` function will compute the Taylor polynomial for a given $n$. For example, here is the series expansion to $10$ terms of the function $\log(1+x)$ about $c=0$:
```{julia}
@@ -803,15 +803,7 @@ Now, $2s = m - s\cdot m$, so the above can be reworked to be $\log(1+m) = m - s\
(For larger values of $m$, a similar, but different approximation, can be used to minimize floating point errors.)
How big can the error be between this *approximations* and $\log(1+m)$? We plot to see how big $s$ can be:
```{julia}
@syms v
plot(v/(2+v), sqrt(2)/2 - 1, sqrt(2)-1)
```
This shows, $s$ is as big as
How big can the error be between this *approximations* and $\log(1+m)$? The expression $m/(2+m)$ increases for $m > 0$, so, on this interval $s$ is as big as
```{julia}
@@ -822,17 +814,17 @@ The error term is like $2/19 \cdot \xi^{19}$ which is largest at this value of
```{julia}
(2/19)*Max^19
(2/19) * Max^19
```
Basically that is machine precision. Which means, that as far as can be told on the computer, the value produced by $2s + s \cdot p$ is about as accurate as can be done.
To try this out to compute $\log(5)$. We have $5 = 2^2(1+0.25)$, so $k=2$ and $m=0.25$.
We try this out to compute $\log(5)$. We have $5 = 2^2(1+ 1/4)$, so $k=2$ and $m=1/4$.
```{julia}
k, m = 2, 0.25
k, m = 2, 1/4
s = m / (2+m)
pₗ = 2 * sum(s^(2i)/(2i+1) for i in 1:8) # where the polynomial approximates the logarithm...
@@ -1209,7 +1201,10 @@ $$
$$
h(x)=b_0 + b_1 (x-x_n) + b_2(x-x_n)(x-x_{n-1}) + \cdots + b_n (x-x_n)(x-x_{n-1})\cdot\cdots\cdot(x-x_1).
\begin{align*}
h(x)&=b_0 + b_1 (x-x_n) + b_2(x-x_n)(x-x_{n-1}) + \cdots \\
&+ b_n (x-x_n)(x-x_{n-1})\cdot\cdots\cdot(x-x_1).
\end{align*}
$$
These two polynomials are of degree $n$ or less and have $u(x) = h(x)-g(x)=0$, by uniqueness. So the coefficients of $u(x)$ are $0$. We have that the coefficient of $x^n$ must be $a_n-b_n$ so $a_n=b_n$. Our goal is to express $a_n$ in terms of $a_{n-1}$ and $b_{n-1}$. Focusing on the $x^{n-1}$ term, we have: