use quarto, not Pluto to render pages
15
.github/workflows/TagBot.yml
vendored
@ -1,15 +0,0 @@
|
||||
name: TagBot
|
||||
on:
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
TagBot:
|
||||
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: JuliaRegistries/TagBot@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
ssh: ${{ secrets.DOCUMENTER_KEY }}
|
||||
1
.github/workflows/documentation.yml
vendored
@ -9,6 +9,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: ${{ false }} # disable documenter for now
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
25
.github/workflows/publish.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
on:
|
||||
push:
|
||||
branches: main
|
||||
|
||||
name: Quarto Publish
|
||||
|
||||
jobs:
|
||||
build-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Quarto
|
||||
uses: quarto-dev/quarto-actions/setup@v2
|
||||
|
||||
- name: Render and Publish
|
||||
uses: quarto-dev/quarto-actions/publish@v2
|
||||
with:
|
||||
target: gh-pages
|
||||
path: quarto/
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@ -16,7 +16,7 @@ const frontmatter = (
|
||||
description = "Calculus with Julia: The `DifferentialEquations` suite",
|
||||
tags = ["CalculusWithJulia", "odes", "the `differentialequations` suite"],
|
||||
);
|
||||
fig_size = (600, 400)
|
||||
fig_size = (800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
@ -152,12 +152,8 @@ end
|
||||
|
||||
The notation `du` is suggestive of both the derivative and a small increment. The mathematical formulation follows the derivative, the numeric solution uses a time step and increments the solution over this time step. The `Tsit5()` solver, used here, adaptively chooses a time step, `dt`; were the `Euler` method used, this time step would need to be explicit.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The `sir!` function has the trailing `!` indicating -- by convention -- it *mutates* its first value, `du`. In this case, through an assignment, as in `du[1]=ds`. This could use some explanation. The *binding* `du` refers to the *container* holding the ``3`` values, whereas `du[1]` refers to the first value in that container. So `du[1]=ds` changes the first value, but not the *binding* of `du` to the container. That is, `du` mutates. This would be quite different were the call `du = [ds,di,dr]` which would create a new *binding* to a new container and not mutate the values in the original container.
|
||||
""", title="Mutation not re-binding")
|
||||
```
|
||||
|
||||
!!! note "Mutation not re-binding"
|
||||
The `sir!` function has the trailing `!` indicating -- by convention -- it *mutates* its first value, `du`. In this case, through an assignment, as in `du[1]=ds`. This could use some explanation. The *binding* `du` refers to the *container* holding the ``3`` values, whereas `du[1]` refers to the first value in that container. So `du[1]=ds` changes the first value, but not the *binding* of `du` to the container. That is, `du` mutates. This would be quite different were the call `du = [ds,di,dr]` which would create a new *binding* to a new container and not mutate the values in the original container.
|
||||
|
||||
With the update function defined, the problem is setup and a solution found with in the same manner:
|
||||
|
||||
@ -289,12 +285,8 @@ end
|
||||
|
||||
This function ``W`` is just a constant above, but can be easily modified as desired.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The "standard" trick is to take a second order ODE like ``u''(t)=u`` and turn this into two coupled ODEs by using a new name: ``v=u'(t)`` and then ``v'(t) = u(t)``. In this application, there are ``4`` equations, as we have *both* ``x''`` and ``y''`` being so converted. The first and second components of ``du`` are new variables, the third and fourth show the original equation.
|
||||
""", title="A second-order ODE is a coupled first-order ODE")
|
||||
```
|
||||
|
||||
!!! note "A second-order ODE is a coupled first-order ODE"
|
||||
The "standard" trick is to take a second order ODE like ``u''(t)=u`` and turn this into two coupled ODEs by using a new name: ``v=u'(t)`` and then ``v'(t) = u(t)``. In this application, there are ``4`` equations, as we have *both* ``x''`` and ``y''`` being so converted. The first and second components of ``du`` are new variables, the third and fourth show the original equation.
|
||||
|
||||
The initial conditions are specified through:
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ const frontmatter = (
|
||||
description = "Calculus with Julia: Euler's method",
|
||||
tags = ["CalculusWithJulia", "odes", "euler's method"],
|
||||
);
|
||||
fig_size = (600, 400)
|
||||
fig_size = (800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
@ -829,6 +829,6 @@ choices = [
|
||||
"The solution is identical to that of the approximation found by linearization of the sine term",
|
||||
"The solution has a constant amplitude, but its period is slightly *shorter* than that of the approximate solution found by linearization",
|
||||
"The solution has a constant amplitude, but its period is slightly *longer* than that of the approximate solution found by linearization"]
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
@ -93,8 +93,11 @@ x'(t) = v(t) = v_0 + a (t - t_0), \quad x(t_0) = x_0.
|
||||
Again, we can integrate to get an answer for any value $t$:
|
||||
|
||||
```math
|
||||
x(t) - x(t_0) = \int_{t_0}^t \frac{dv}{dt} dt = (v_0t + \frac{1}{2}a t^2 - at_0 t) |_{t_0}^t =
|
||||
(v_0 - at_0)(t - t_0) + \frac{1}{2} a (t^2 - t_0^2).
|
||||
\begin{align*}
|
||||
x(t) - x(t_0) &= \int_{t_0}^t \frac{dv}{dt} dt \\
|
||||
&= (v_0t + \frac{1}{2}a t^2 - at_0 t) |_{t_0}^t \\
|
||||
&= (v_0 - at_0)(t - t_0) + \frac{1}{2} a (t^2 - t_0^2).
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
There are three constants: the initial value for the independent variable, $t_0$, and the two initial values for the velocity and position, $v_0, x_0$. Assuming $t_0 = 0$, we can simplify the above to get a formula familiar from introductory physics:
|
||||
@ -174,13 +177,15 @@ A graph of the solution for $T_0=200$ and $T_a=72$ and $r=1/2$ is made
|
||||
as follows. We've added a few line segments from the defining formula,
|
||||
and see that they are indeed tangent to the solution found for the differential equation.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
T0, Ta, r = 200, 72, 1/2
|
||||
f(u, t) = -r*(u - Ta)
|
||||
v(t) = Ta + (T0 - Ta) * exp(-r*t)
|
||||
p = plot(v, 0, 6, linewidth=4, legend=false)
|
||||
[plot!(p, x -> v(a) + f(v(a), a) * (x-a), 0, 6) for a in 1:2:5]
|
||||
p
|
||||
```julia; echo=false
|
||||
let
|
||||
T0, Ta, r = 200, 72, 1/2
|
||||
f(u, t) = -r*(u - Ta)
|
||||
v(t) = Ta + (T0 - Ta) * exp(-r*t)
|
||||
p = plot(v, 0, 6, linewidth=4, legend=false)
|
||||
[plot!(p, x -> v(a) + f(v(a), a) * (x-a), 0, 6) for a in 1:2:5]
|
||||
p
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
@ -725,10 +730,8 @@ plot!(f, linewidth=5)
|
||||
|
||||
In general, if the first-order equation is written as $y'(x) = F(y,x)$, then we plot a "function" that takes $(x,y)$ and returns an $x$ value of $1$ and a $y$ value of $F(y,x)$, so the slope is $F(y,x)$.
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""The order of variables in $F(y,x)$ is conventional with the equation $y'(x) = F(y(x),x)$.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The order of variables in $F(y,x)$ is conventional with the equation $y'(x) = F(y(x),x)$.
|
||||
|
||||
|
||||
The plots are also useful for illustrating solutions for different initial conditions:
|
||||
@ -780,8 +783,8 @@ choices = [
|
||||
"``[-1, 4]``",
|
||||
"``[-1, 0]``",
|
||||
"``[1-\\sqrt{5}, 1 + \\sqrt{5}]``"]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -891,8 +894,8 @@ eqn = diff(x^2*D(u)(x), x)
|
||||
out = dsolve(eqn, u(x), ics=Dict(u(1)=>2, u(10) => 1)) |> rhs
|
||||
out(5) # 10/9
|
||||
choices = ["``10/9``", "``3/2``", "``9/10``", "``8/9``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -909,6 +912,6 @@ choices = [
|
||||
"The limit does not exist, but the limit to `oo` gives a quadratic polynomial in `x`, mirroring the first part of that example.",
|
||||
"The limit does not exist -- there is a singularity -- as seen by setting `gamma=0`."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -15,7 +15,7 @@ const frontmatter = (
|
||||
description = "Calculus with Julia: The problem-algorithm-solve interface",
|
||||
tags = ["CalculusWithJulia", "odes", "the problem-algorithm-solve interface"],
|
||||
);
|
||||
fig_size = (600, 400)
|
||||
fig_size = (800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
|
||||
107
CwJ/alternatives/interval_arithmetic.__jmd__
Normal file
@ -0,0 +1,107 @@
|
||||
# Using interval arithemetic
|
||||
|
||||
Highlighted here is the use of interval arithmetic for calculus problems.
|
||||
|
||||
Unlike floating point math, where floating point values are an *approximation* to real numbers, interval arithmetic uses *interval* which are **guaranteed** to contain the given value. We use the `IntervalArithmetic` package and friends to work below, but note there is nothing magic about the concept.
|
||||
|
||||
## Basic XXX
|
||||
|
||||
|
||||
|
||||
## Using `IntervalRootFinding` to identify zeros of a function
|
||||
|
||||
The `IntervalRootFinding` package provides a more *rigorous* alternative to `find_zeros`. This packages leverages the interval arithmetic features of `IntervalArithmetic`.
|
||||
The `IntervalRootFinding` package provides a function `roots`, with usage similar to `find_zeros`. Intervals are specified with the notation `a..b`. In the following, we *qualify* `roots` to not conflict with the `roots` function from `SymPy`, which has already been loaded:
|
||||
|
||||
```julia
|
||||
import IntervalArithmetic
|
||||
import IntervalRootFinding
|
||||
```
|
||||
|
||||
```julia
|
||||
u(x) = sin(x) - 0.1*x^2 + 1
|
||||
𝑱 = IntervalArithmetic.Interval(-10, 10) # cumbersome -10..10; needed here: .. means something in CalculusWithJulia
|
||||
rts = IntervalRootFinding.roots(u, 𝑱)
|
||||
```
|
||||
|
||||
The "zeros" are returned with an enclosing interval and a flag, which for the above indicates a unique zero in the interval.
|
||||
|
||||
The intervals with a unique answer can be filtered and refined with a construct like the following:
|
||||
|
||||
```julia
|
||||
[find_zero(u, (IntervalArithmetic.interval(I).lo, IntervalArithmetic.interval(I).hi)) for I in rts if I.status == :unique]
|
||||
```
|
||||
|
||||
The midpoint of the returned interval can be found by composing the `mid` function with the `interval` function of the package:
|
||||
|
||||
```julia
|
||||
[(IntervalArithmetic.mid ∘ IntervalArithmetic.interval)(I) for I in rts if I.status == :unique]
|
||||
```
|
||||
|
||||
|
||||
|
||||
For some problems, `find_zeros` is more direct, as with this one:
|
||||
|
||||
|
||||
```julia
|
||||
find_zeros(u, (-10, 10))
|
||||
```
|
||||
|
||||
Which can be useful if there is some prior understanding of the zeros expected to be found.
|
||||
However, `IntervalRootFinding` is more efficient computationally and *offers a guarantee* on the values found.
|
||||
|
||||
|
||||
|
||||
For functions where roots are not "unique" a different output may appear:
|
||||
|
||||
```julia; hold=true;
|
||||
f(x) = x*(x-1)^2
|
||||
rts = IntervalRootFinding.roots(f, 𝑱)
|
||||
```
|
||||
|
||||
The interval labeled `:unknown` contains a `0`, but it can't be proved by `roots`.
|
||||
|
||||
|
||||
Interval arithmetic finds **rigorous** **bounds** on the range of `f` values over a closed interval `a..b` (the range is `f(a..b)`). "Rigorous" means the bounds are truthful and account for possible floating point issues. "Bounds" means the answer lies within, but the bound need not be the answer.
|
||||
|
||||
This allows one -- for some functions -- to answer affirmatively questions like:
|
||||
|
||||
* Is the function *always* positive on `a..b`? Negative? This can be done by checking if `0` is in the bound given by `f(a..b)`. If it isn't then one of the two characterizations is true.
|
||||
|
||||
* Is the function *strictly increasing* on `a..b`? Strictly decreasing? These questions can be answered using the (upcoming) [derivative](../derivatives/derivatives.html). If the derivative is positive on `a..b` then `f` is strictly increasing, if negative on `a..b` then `f` is strictly decreasing. Finding the derivative can be done within the `IntervalArithmetic` framework using [automatic differentiation](../derivatives/numeric_derivatives.html), a blackbox operation denoted `f'` below.
|
||||
|
||||
Combined, for some functions and some intervals these two questions can be answered affirmatively:
|
||||
|
||||
* the interval does not contain a zero (`0 !in f(a..b)`)
|
||||
* over the interval, the function crosses the `x` axis *once* (`f(a..a)` and `f(b..b)` are one positive and one negative *and* `f` is strictly monotone, or `0 !in f'(a..b)`)
|
||||
|
||||
This allows the following (simplified) bisection-like algorithm to be used:
|
||||
|
||||
* consider an interval `a..b`
|
||||
* if the function is *always* positive or negative, it can be discarded as no zero can be in the interval
|
||||
* if the function crosses the `x` axis *once* over this interval **then** there is a "unique" zero in the interval and the interval can be marked so and set aside
|
||||
* if neither of the above *and* `a..b` is not too small already, then *sub-divide* the interval and repeat the above with *both* smaller intervals
|
||||
* if `a..b` is too small, stop and mark it as "unknown"
|
||||
|
||||
When terminated there will be intervals with unique zeros flagged and smaller intervals with an unknown status.
|
||||
|
||||
Compared to the *bisection* algorithm -- which only knows for some intervals if that interval has one or more crossings -- this algorithm gives a more rigorous means to get all the zeros in `a..b`.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
For a last example of the value of this package, this function, which appeared in our discussion on limits, is *positive* for **every** floating point number, but has two zeros snuck in at values within the floating point neighbors of $15/11$
|
||||
|
||||
```julia
|
||||
t(x) = x^2 + 1 +log(abs( 11*x-15 ))/99
|
||||
```
|
||||
|
||||
The `find_zeros` function will fail on identifying any potential zeros of this function. Even the basic call of `roots` will fail, due to it relying on some smoothness of `f`. However, explicitly asking for `Bisection` shows the *potential* for one or more zeros near $15/11$:
|
||||
|
||||
```julia
|
||||
IntervalRootFinding.roots(t, 𝑱, IntervalRootFinding.Bisection)
|
||||
```
|
||||
|
||||
(The basic algorithm above can be sped up using a variant of [Newton's](../derivatives/newton_method.html) method, this variant assumes some "smoothness" in the function `f`, whereas this `f` is not continuous at the point ``x=15/11``.)
|
||||
@ -1,6 +1,8 @@
|
||||
[deps]
|
||||
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
||||
EllipsisNotation = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
|
||||
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
|
||||
ImplicitPlots = "55ecb840-b828-11e9-1645-43f4a9f9ace7"
|
||||
IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253"
|
||||
IntervalConstraintProgramming = "138f1668-1576-5ad7-91b9-7425abbf3153"
|
||||
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
|
||||
|
||||
@ -15,7 +15,7 @@ using Polynomials # some name clash with SymPy
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
fig_size=(600, 400)
|
||||
fig_size=(800, 600)
|
||||
const frontmatter = (
|
||||
title = "Curve Sketching",
|
||||
description = "Calculus with Julia: Curve Sketching",
|
||||
@ -331,8 +331,8 @@ L"Just vertical asymptotes at $x=-1$ and $x=1$",
|
||||
L"Vertical asymptotes at $x=-1$ and $x=1$ and a horizontal asymptote $y=1$",
|
||||
L"Vertical asymptotes at $x=-1$ and $x=1$ and a slant asymptote"
|
||||
]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -474,8 +474,8 @@ choices = [
|
||||
"The exponential growth model",
|
||||
"The limit does not exist",
|
||||
"The limit is ``P_0``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
@ -493,8 +493,8 @@ choices = [
|
||||
"The function will have more curvature when the second derivative is large, so there needs to be more points to capture the shape",
|
||||
"The function will be much larger (in absolute value) when the second derivative is large, so there needs to be more points to capture the shape",
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
@ -514,8 +514,8 @@ choices = [
|
||||
"An informative graph only needs to show one or two periods, as others can be inferred.",
|
||||
"An informative graph need only show a part of the period, as the rest can be inferred.",
|
||||
L"An informative graph needs to show several periods, as that will allow proper computation for the $y$ axis range."]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Why should asymptotics matter?
|
||||
@ -526,8 +526,8 @@ L"A vertical asymptote can distory the $y$ range, so it is important to avoid to
|
||||
L"A horizontal asymptote must be plotted from $-\infty$ to $\infty$",
|
||||
"A slant asymptote must be plotted over a very wide domain so that it can be identified."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Monotonicity means increasing or decreasing. This is important for what reason?
|
||||
@ -538,6 +538,6 @@ choices = [
|
||||
"For monotonic regions, a function is basically a straight line",
|
||||
"For monotonic regions, the function will have a vertical asymptote, so the region should not be plotted"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -19,7 +19,7 @@ const frontmatter = (
|
||||
tags = ["CalculusWithJulia", "derivatives", "derivatives"],
|
||||
);
|
||||
|
||||
fig_size=(600, 400)
|
||||
fig_size=(800, 600)
|
||||
|
||||
nothing
|
||||
```
|
||||
@ -1199,16 +1199,16 @@ At which of these points $c= 1/2, 1, 3/2$ is the derivative negative?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``1/2``", "``1``", "``3/2``"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
Which value looks bigger from reading the graph:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``f(1)``", "``f(3/2)``"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
At $0.708 \dots$ and $1.65\dots$ the derivative has a common value. What is it?
|
||||
@ -1229,8 +1229,8 @@ At $x = -2.5$ the derivative is postive or negative?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["positive", "negative"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1238,16 +1238,16 @@ At $x=0$ the derivative is postive or negative?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["positive", "negative"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
At $x = 2.5$ the derivative is postive or negative?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["positive", "negative"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1256,8 +1256,8 @@ Compute the derivative of $e^x$ using `limit`. What do you get?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``e^x``", "``x^e``", "``(e-1)x^e``", "``e x^{(e-1)}``", "something else"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1266,8 +1266,8 @@ Compute the derivative of $x^e$ using `limit`. What do you get?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``e^x``", "``x^e``", "``(e-1)x^e``", "``e x^{(e-1)}``", "something else"]
|
||||
ans = 5
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 5
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1276,8 +1276,8 @@ Compute the derivative of $e^{e\cdot x}$ using `limit`. What do you get?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``e^x``", "``x^e``", "``(e-1)x^e``", "``e x^{(e-1)}``", "``e \\cdot e^{e\\cdot x}``", "something else"]
|
||||
ans = 5
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 5
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1295,8 +1295,8 @@ choices = [
|
||||
L" $1$, as this is clearly the analog of the limit of $\sin(h)/h$.",
|
||||
L"Does not exist. The answer is $0/0$ which is undefined",
|
||||
L" $0$, as this expression is the derivative of cosine at $0$. The answer follows, as cosine clearly has a tangent line with slope $0$ at $x=0$."]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1310,8 +1310,8 @@ choices = [
|
||||
"``f'(x) = f(x)``",
|
||||
"``f'(x) = -f(x)``"
|
||||
]
|
||||
ans= 1
|
||||
radioq(choices, ans)
|
||||
answ= 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1326,8 +1326,8 @@ choices = [
|
||||
"``f''(x) = -g(x)``",
|
||||
"``f''(x) = f(x)``",
|
||||
"``f''(x) = -f(x)``"]
|
||||
ans= 3
|
||||
radioq(choices, ans)
|
||||
answ= 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1381,8 +1381,8 @@ L"If the graphs of $f$ and $g$ are translations up and down, the tangent line at
|
||||
L"If the graphs of $f$ and $g$ are rescalings of each other through $g(x)=f(x/c)$, $c > 1$. Then the tangent line for corresponding points is the same.",
|
||||
L"If the graphs of $f$ and $g$ are rescalings of each other through $g(x)=cf(x)$, $c > 1$. Then the tangent line for corresponding points is the same."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1409,8 +1409,8 @@ choices = [
|
||||
"``f'(x) = -k^2 \\cdot f(x)``",
|
||||
"``f''(x) = k^2 \\cdot f(x)``",
|
||||
"``f''(x) = -k^2 \\cdot f(x)``"]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1424,8 +1424,8 @@ choices = [
|
||||
"``f'(x) = -k^2 \\cdot f(x)``",
|
||||
"``f''(x) = k^2 \\cdot f(x)``",
|
||||
"``f''(x) = -k^2 \\cdot f(x)``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
|
||||
@ -416,17 +416,19 @@ g' + 0 - 0 - 0 + g'-sign
|
||||
Consider the function $f(x) = x^2$. Over this function we draw some
|
||||
secant lines for a few pairs of $x$ values:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
f(x) = x^2
|
||||
seca(f,a,b) = x -> f(a) + (f(b) - f(a)) / (b-a) * (x-a)
|
||||
p = plot(f, -2, 3, legend=false, linewidth=5, xlim=(-2,3), ylim=(-2, 9))
|
||||
plot!(p,seca(f, -1, 2))
|
||||
a,b = -1, 2; xs = range(a, stop=b, length=50)
|
||||
plot!(xs, seca(f, a, b).(xs), linewidth=5)
|
||||
plot!(p,seca(f, 0, 3/2))
|
||||
a,b = 0, 3/2; xs = range(a, stop=b, length=50)
|
||||
plot!(xs, seca(f, a, b).(xs), linewidth=5)
|
||||
p
|
||||
```julia; echo=false
|
||||
let
|
||||
f(x) = x^2
|
||||
seca(f,a,b) = x -> f(a) + (f(b) - f(a)) / (b-a) * (x-a)
|
||||
p = plot(f, -2, 3, legend=false, linewidth=5, xlim=(-2,3), ylim=(-2, 9))
|
||||
plot!(p,seca(f, -1, 2))
|
||||
a,b = -1, 2; xs = range(a, stop=b, length=50)
|
||||
plot!(xs, seca(f, a, b).(xs), linewidth=5)
|
||||
plot!(p,seca(f, 0, 3/2))
|
||||
a,b = 0, 3/2; xs = range(a, stop=b, length=50)
|
||||
plot!(xs, seca(f, a, b).(xs), linewidth=5)
|
||||
p
|
||||
end
|
||||
```
|
||||
|
||||
The graph attempts to illustrate that for this function the secant
|
||||
@ -573,11 +575,11 @@ One way to visualize the second derivative test is to *locally* overlay on a cri
|
||||
```julia; hold=true;
|
||||
f(x) = sin(x) + sin(2x) + sin(3x)
|
||||
p = plot(f, 0, 2pi, legend=false, color=:blue, linewidth=3)
|
||||
cps = fzeros(f', 0, 2pi)
|
||||
h = 0.5
|
||||
cps = find_zeros(f', (0, 2pi))
|
||||
Δ = 0.5
|
||||
for c in cps
|
||||
parabola(x) = f(c) + (f''(c)/2) * (x-c)^2
|
||||
plot!(parabola, c-h, c+h, color=:red, linewidth=5, alpha=0.6)
|
||||
plot!(parabola, c - Δ, c + Δ, color=:red, linewidth=5, alpha=0.6)
|
||||
end
|
||||
p
|
||||
```
|
||||
@ -637,16 +639,18 @@ find_zeros(k'', -3, 3)
|
||||
A car travels from a stop for 1 mile in 2 minutes. A graph of its
|
||||
position as a function of time might look like any of these graphs:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
v(t) = 30/60*t
|
||||
w(t) = t < 1/2 ? 0.0 : (t > 3/2 ? 1.0 : (t-1/2))
|
||||
y(t) = 1 / (1 + exp(-t))
|
||||
y1(t) = y(2(t-1))
|
||||
y2(t) = y1(t) - y1(0)
|
||||
y3(t) = 1/y2(2) * y2(t)
|
||||
plot(v, 0, 2, label="f1")
|
||||
plot!(w, label="f2")
|
||||
plot!(y3, label="f3")
|
||||
```julia; echo=false
|
||||
let
|
||||
v(t) = 30/60*t
|
||||
w(t) = t < 1/2 ? 0.0 : (t > 3/2 ? 1.0 : (t-1/2))
|
||||
y(t) = 1 / (1 + exp(-t))
|
||||
y1(t) = y(2(t-1))
|
||||
y2(t) = y1(t) - y1(0)
|
||||
y3(t) = 1/y2(2) * y2(t)
|
||||
plot(v, 0, 2, label="f1")
|
||||
plot!(w, label="f2")
|
||||
plot!(y3, label="f3")
|
||||
end
|
||||
```
|
||||
|
||||
All three graphs have the same *average* velocity which is just the
|
||||
@ -696,8 +700,8 @@ choices=[
|
||||
"``(-5, -4.2)``",
|
||||
"``(-5, -4.2)`` and ``(-2.5, 0)``",
|
||||
"``(-4.2, -2.5)``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -718,8 +722,8 @@ choices=[
|
||||
"``(-25.0, 0.0)``",
|
||||
"``(-5.0, -4.0)`` and ``(-4, -3)``",
|
||||
"``(-4.0, -3.0)``"]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -740,8 +744,8 @@ choices=[
|
||||
"``(-4.7, -3.0)``",
|
||||
"``(-0.17, 0.17)``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -763,8 +767,8 @@ choices=[
|
||||
"``(-0.6, 0.6)``",
|
||||
" ``(-3.0, -0.6)`` and ``(0.6, 3.0)``"
|
||||
]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -786,8 +790,8 @@ choices = [
|
||||
"That the critical point at ``0`` is a relative maximum",
|
||||
"That the critical point at ``0`` is a relative minimum"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -801,8 +805,8 @@ choices = [
|
||||
" ``f(x)`` is continuous and differentiable at ``2`` and has a critical point",
|
||||
" ``f(x)`` is continuous and differentiable at ``2`` and has a critical point that is a relative minimum by the second derivative test"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -810,22 +814,26 @@ radioq(choices, ans, keep_order=true)
|
||||
|
||||
Find the smallest critical point of $f(x) = x^3 e^{-x}$.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
f(x)= x^3*exp(-x)
|
||||
cps = find_zeros(D(f), -5, 10)
|
||||
val = minimum(cps)
|
||||
numericq(val)
|
||||
```julia; echo=false
|
||||
let
|
||||
f(x)= x^3*exp(-x)
|
||||
cps = find_zeros(D(f), -5, 10)
|
||||
val = minimum(cps)
|
||||
numericq(val)
|
||||
end
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
How many critical points does $f(x) = x^5 - x + 1$ have?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
f(x) = x^5 - x + 1
|
||||
cps = find_zeros(D(f), -3, 3)
|
||||
val = length(cps)
|
||||
numericq(val)
|
||||
```julia; echo=false
|
||||
let
|
||||
f(x) = x^5 - x + 1
|
||||
cps = find_zeros(D(f), -3, 3)
|
||||
val = length(cps)
|
||||
numericq(val)
|
||||
end
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -833,11 +841,13 @@ numericq(val)
|
||||
How many inflection points does $f(x) = x^5 - x + 1$ have?
|
||||
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
f(x) = x^5 - x + 1
|
||||
cps = find_zeros(D(f,2), -3, 3)
|
||||
val = length(cps)
|
||||
numericq(val)
|
||||
```julia; echo=false
|
||||
let
|
||||
f(x) = x^5 - x + 1
|
||||
cps = find_zeros(D(f,2), -3, 3)
|
||||
val = length(cps)
|
||||
numericq(val)
|
||||
end
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -850,8 +860,8 @@ choices = [
|
||||
"No, the second derivative test is possibly inconclusive",
|
||||
"Yes"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -865,15 +875,17 @@ choices = [
|
||||
"No, the second derivative test is possibly inconclusive if ``c=0``, but otherwise yes",
|
||||
"Yes"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
f(x) = exp(-x) * sin(pi*x)
|
||||
plot(D(f), 0, 3)
|
||||
```julia; echo=false
|
||||
let
|
||||
f(x) = exp(-x) * sin(pi*x)
|
||||
plot(D(f), 0, 3)
|
||||
end
|
||||
```
|
||||
|
||||
The graph shows $f'(x)$. Is it possible that $f(x) = e^{-x} \sin(\pi x)$?
|
||||
@ -931,8 +943,8 @@ choices = [
|
||||
"The critical points are at ``x=1`` (a relative minimum), ``x=2`` (not a relative extrema), and ``x=3`` (a relative minimum).",
|
||||
"The critical points are at ``x=1`` (a relative minimum), ``x=2`` (a relative minimum), and ``x=3`` (a relative minimum).",
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
@ -945,8 +957,8 @@ choices = [
|
||||
"The function is decreasing over ``(-\\infty, 1)`` and increasing over ``(1, \\infty)``",
|
||||
"The function is negative over ``(-\\infty, 1)`` and positive over ``(1, \\infty)``",
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
@ -957,8 +969,8 @@ While driving we accelerate to get through a light before it turns red. However,
|
||||
choices = ["A zero of the function",
|
||||
"A critical point for the function",
|
||||
"An inflection point for the function"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
@ -237,17 +237,12 @@ Not quite what we expect, perhaps, but substituting in ``f(x)/g(x)`` for ``y`` g
|
||||
\frac{dy}{dx} = \frac{f'(x) - \frac{f(x)}{g(x)} g'(x)}{g(x)} = \frac{f'(x) g(x) - f(x) g'(x)}{g(x)^2}.
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
|
||||
In this example we mix notations using ``g'(x)`` to
|
||||
represent a derivative of ``g`` with respect to ``x`` and ``dy/dx`` to
|
||||
represent the derivative of ``y`` with respect to ``x``. This is done to
|
||||
emphasize the value that we are solving for. It is just a convention
|
||||
though, we could just as well have used the "prime" notation for each.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
In this example we mix notations using ``g'(x)`` to
|
||||
represent a derivative of ``g`` with respect to ``x`` and ``dy/dx`` to
|
||||
represent the derivative of ``y`` with respect to ``x``. This is done to
|
||||
emphasize the value that we are solving for. It is just a convention
|
||||
though, we could just as well have used the "prime" notation for each.
|
||||
|
||||
|
||||
##### Example: Graphing a tangent line
|
||||
@ -399,17 +394,11 @@ Basically this includes all the same steps as if done "by hand." Some effort cou
|
||||
values for the parameters been substituted initially, but not doing so
|
||||
shows their dependence in the derivative.
|
||||
|
||||
```julia; echo=false
|
||||
alert("The use of `lambdify(H)` is needed to turn the symbolic expression, `H`, into a function.")
|
||||
```
|
||||
!!! warning
|
||||
The use of `lambdify(H)` is needed to turn the symbolic expression, `H`, into a function.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
|
||||
While `SymPy` itself has the `plot_implicit` function for plotting implicit equations, this works only with `PyPlot`, not `Plots`, so we use the `ImplicitPlots` package in these examples.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
While `SymPy` itself has the `plot_implicit` function for plotting implicit equations, this works only with `PyPlot`, not `Plots`, so we use the `ImplicitPlots` package in these examples.
|
||||
|
||||
|
||||
## Higher order derivatives
|
||||
@ -818,8 +807,8 @@ choices = [
|
||||
"``b \\cdot (1 - (x/a)^n)^{1/n}``",
|
||||
"``-(x/a)^n / (y/b)^n``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -863,8 +852,8 @@ choices = [
|
||||
"``2xy / (x^2 + a^2)``",
|
||||
"``a^3/(x^2 + a^2)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -885,8 +874,8 @@ Using Implicit differentiation, find when ``dy/dx = 0``.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``y^2 = 3x/a``", "``y=3x^2/a``", "``y=a/(3x^2)``", "``y^2=a/(3x)``"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Substituting the correct value of ``y``, above, into the defining equation gives what value for ``x``:
|
||||
@ -898,8 +887,8 @@ choices=[
|
||||
"``x=(1/2) a^3 3^{1/3}``",
|
||||
"``x=(1/3) a^2 2^{1/2}``"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -924,8 +913,8 @@ If ``y>0`` is the sign positive or negative?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["positive", "negative", "Can be both"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
If ``x>0`` is the sign positive or negative?
|
||||
@ -933,16 +922,16 @@ If ``x>0`` is the sign positive or negative?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["positive", "negative", "Can be both"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
When ``x>0``, the graph of the equation is...
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["concave up", "concave down", "both concave up and down"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ using SymPy
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
using Roots
|
||||
|
||||
fig_size=(600, 400)
|
||||
fig_size=(800, 600)
|
||||
const frontmatter = (
|
||||
title = "L'Hospital's Rule",
|
||||
description = "Calculus with Julia: L'Hospital's Rule",
|
||||
@ -79,10 +79,10 @@ likely due to one of the Bernoulli brothers.
|
||||
> ``\lim_{x \rightarrow c+}f(x)/g(x) = L``.
|
||||
|
||||
|
||||
That is *if* the right limit of ``f(x)/g(x)`` is indeterminate of the form ``0/0``,
|
||||
but the right limit of ``f'(x)/g'(x)`` is known, possibly by simple
|
||||
continuity, then the right limit of ``f(x)/g(x)`` exists and is equal to that
|
||||
of ``f'(x)/g'(x)``.
|
||||
That is *if* the right limit of ``f(x)/g(x)`` is indeterminate of the
|
||||
form ``0/0``, but the right limit of ``f'(x)/g'(x)`` is known,
|
||||
possibly by simple continuity, then the right limit of ``f(x)/g(x)``
|
||||
exists and is equal to that of ``f'(x)/g'(x)``.
|
||||
|
||||
The rule equally applies to *left limits* and *limits* at ``c``. Later it will see there are other generalizations.
|
||||
|
||||
@ -102,12 +102,8 @@ this answer is as it is, but we don't need to think in terms of
|
||||
\approx x``, as ``\cos(0)`` appears as the coefficient.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
In [Gruntz](http://www.cybertester.com/data/gruntz.pdf), in a reference attributed to Speiss, we learn that L'Hospital was a French Marquis who was taught in ``1692`` the calculus of Leibniz by Johann Bernoulli. They made a contract obliging Bernoulli to leave his mathematical inventions to L'Hospital in exchange for a regular compensation. This result was discovered in ``1694`` and appeared in L'Hospital's book of ``1696``.
|
||||
"""; title="Bernoulli-de l'Hospital")
|
||||
```
|
||||
|
||||
!!! note
|
||||
In [Gruntz](http://www.cybertester.com/data/gruntz.pdf), in a reference attributed to Speiss, we learn that L'Hospital was a French Marquis who was taught in ``1692`` the calculus of Leibniz by Johann Bernoulli. They made a contract obliging Bernoulli to leave his mathematical inventions to L'Hospital in exchange for a regular compensation. This result was discovered in ``1694`` and appeared in L'Hospital's book of ``1696``.
|
||||
|
||||
##### Examples
|
||||
|
||||
@ -121,10 +117,8 @@ In [Gruntz](http://www.cybertester.com/data/gruntz.pdf), in a reference attribut
|
||||
= \lim_{x \rightarrow 0}\frac{a^x - 1}{x}.
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""Why rewrite in the "opposite" direction? Because the theorem's result -- ``L`` is the limit -- is only true if the related limit involving the derivative exists. We don't do this in the following, but did so here to emphasize the need for the limit of the ratio of the derivatives to exist.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Why rewrite in the "opposite" direction? Because the theorem's result -- ``L`` is the limit -- is only true if the related limit involving the derivative exists. We don't do this in the following, but did so here to emphasize the need for the limit of the ratio of the derivatives to exist.
|
||||
|
||||
- Consider this limit:
|
||||
|
||||
@ -270,7 +264,8 @@ known.
|
||||
|
||||
----
|
||||
|
||||
```julia; hold=true; echo=false; cache=true
|
||||
```julia; echo=false; cache=true
|
||||
let
|
||||
## {{{lhopitals_picture}}}
|
||||
|
||||
function lhopitals_picture_graph(n)
|
||||
@ -286,8 +281,8 @@ function lhopitals_picture_graph(n)
|
||||
## get bounds
|
||||
tl = (x) -> g(0) + m * (x - f(0))
|
||||
|
||||
lx = max(fzero(x -> tl(x) - (-0.05),-1000, 1000), -0.6)
|
||||
rx = min(fzero(x -> tl(x) - (0.25),-1000, 1000), 0.2)
|
||||
lx = max(find_zero(x -> tl(x) - (-0.05), (-1000, 1000)), -0.6)
|
||||
rx = min(find_zero(x -> tl(x) - (0.25), (-1000, 1000)), 0.2)
|
||||
xs = [lx, rx]
|
||||
ys = map(tl, xs)
|
||||
|
||||
@ -319,7 +314,8 @@ gif(anim, imgfile, fps = 1)
|
||||
|
||||
|
||||
plotly()
|
||||
ImageFile(imgfile, caption)
|
||||
ImageFile(imgfile, caption)
|
||||
end
|
||||
```
|
||||
|
||||
## Generalizations
|
||||
@ -556,8 +552,8 @@ nothing
|
||||
```
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 1
|
||||
radioq(lh_choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(lh_choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -565,8 +561,8 @@ radioq(lh_choices, ans, keep_order=true)
|
||||
This function ``f(x) = \sin(x)^{\sin(x)}`` is *indeterminate* at ``x=0``. What type?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans =3
|
||||
radioq(lh_choices, ans, keep_order=true)
|
||||
answ =3
|
||||
radioq(lh_choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -574,8 +570,8 @@ radioq(lh_choices, ans, keep_order=true)
|
||||
This function ``f(x) = (x-2)/(x^2 - 4)`` is *indeterminate* at ``x=2``. What type?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 1
|
||||
radioq(lh_choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(lh_choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -583,8 +579,8 @@ radioq(lh_choices, ans, keep_order=true)
|
||||
This function ``f(x) = (g(x+h) - g(x-h)) / (2h)`` (``g`` is continuous) is *indeterminate* at ``h=0``. What type?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 1
|
||||
radioq(lh_choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(lh_choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -592,8 +588,8 @@ radioq(lh_choices, ans, keep_order=true)
|
||||
This function ``f(x) = x \log(x)`` is *indeterminate* at ``x=0``. What type?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 5
|
||||
radioq(lh_choices, ans, keep_order=true)
|
||||
answ = 5
|
||||
radioq(lh_choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -610,8 +606,8 @@ choices = [
|
||||
"Yes. It is of the form ``0/0``",
|
||||
"No. It is not indeterminate"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -769,6 +765,6 @@ choices = [
|
||||
"``0``",
|
||||
"It does not exist"
|
||||
]
|
||||
ans =1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -641,8 +641,8 @@ choices = [
|
||||
"``1 + x^{1/2}``",
|
||||
"``1 + (1/2) \\cdot x``",
|
||||
"``1 - (1/2) \\cdot x``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -657,8 +657,8 @@ choices = [
|
||||
"``1 + x^k``",
|
||||
"``1 + k \\cdot x``",
|
||||
"``1 - k \\cdot x``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -672,8 +672,8 @@ choices = [
|
||||
"``x``",
|
||||
"``1 - x^2/2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -688,8 +688,8 @@ choices = [
|
||||
"``1 + x``",
|
||||
"``1 - x``"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -705,8 +705,8 @@ choices = [
|
||||
"``1 + x``",
|
||||
"``25``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -719,8 +719,8 @@ value of the tangent line at $(25, f(25))$ at $x=26$.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
tgent(x) = 5 + x/10
|
||||
ans = tgent(1) - sqrt(26)
|
||||
numericq(ans)
|
||||
answ = tgent(1) - sqrt(26)
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -730,8 +730,8 @@ An estimate of some quantity was $12.34$ the actual value was $12$. What was the
|
||||
```julia; hold=true; echo=false
|
||||
est = 12.34
|
||||
act = 12.0
|
||||
ans = (est -act)/act * 100
|
||||
numericq(ans)
|
||||
answ = (est -act)/act * 100
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
|
||||
@ -744,8 +744,8 @@ tl(x) = x
|
||||
x0 = 5 * pi/180
|
||||
est = x0
|
||||
act = sin(x0)
|
||||
ans = (est -act)/act * 100
|
||||
numericq(ans)
|
||||
answ = (est -act)/act * 100
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -754,8 +754,8 @@ The side length of a square is measured roughly to be $2.0$ cm. The actual lengt
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
tl(x) = 4 + 4x
|
||||
ans = tl(.2) - 4
|
||||
numericq(abs(ans))
|
||||
answ = tl(.2) - 4
|
||||
numericq(abs(answ))
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ using CalculusWithJulia.WeaveSupport
|
||||
using Printf
|
||||
using SymPy
|
||||
|
||||
fig_size = (600, 400)
|
||||
fig_size = (800, 600)
|
||||
|
||||
const frontmatter = (
|
||||
title = "The mean value theorem for differentiable functions.",
|
||||
@ -84,19 +84,14 @@ power rule: $f'(x) = 1/3 \cdot x^{-2/3}$, which has a vertical
|
||||
asymptote at $x=0$.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
|
||||
The `cbrt` function is used above, instead of `f(x) = x^(1/3)`, as the
|
||||
latter is not defined for negative `x`. Though it can be for the exact
|
||||
power `1/3`, it can't be for an exact power like `1/2`. This means the
|
||||
value of the argument is important in determining the type of the
|
||||
output - and not just the type of the argument. Having type-stable
|
||||
functions is part of the magic to making `Julia` run fast, so `x^c` is
|
||||
not defined for negative `x` and most floating point exponents.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The `cbrt` function is used above, instead of `f(x) = x^(1/3)`, as the
|
||||
latter is not defined for negative `x`. Though it can be for the exact
|
||||
power `1/3`, it can't be for an exact power like `1/2`. This means the
|
||||
value of the argument is important in determining the type of the
|
||||
output - and not just the type of the argument. Having type-stable
|
||||
functions is part of the magic to making `Julia` run fast, so `x^c` is
|
||||
not defined for negative `x` and most floating point exponents.
|
||||
|
||||
|
||||
Lest you think that continuous functions always have derivatives
|
||||
@ -128,14 +123,9 @@ must also be specified, for a relative maximum there just needs to
|
||||
exist some interval, possibly really small, though it must be bigger
|
||||
than a point.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
|
||||
A hiker can appreciate the difference. A relative maximum would be the
|
||||
crest of any hill, but an absolute maximum would be the summit.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
A hiker can appreciate the difference. A relative maximum would be the
|
||||
crest of any hill, but an absolute maximum would be the summit.
|
||||
|
||||
What does this have to do with derivatives?
|
||||
|
||||
@ -286,19 +276,14 @@ Here the maximum occurs at an endpoint. The critical point $c=0.67\dots$
|
||||
does not produce a maximum value. Rather $f(0.67\dots)$ is an absolute
|
||||
minimum.
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
|
||||
**Absolute minimum** We haven't discussed the parallel problem of
|
||||
!!! note
|
||||
**Absolute minimum** We haven't discussed the parallel problem of
|
||||
absolute minima over a closed interval. By considering the function
|
||||
$h(x) = - f(x)$, we see that the any thing true for an absolute
|
||||
maximum should hold in a related manner for an absolute minimum, in
|
||||
particular an absolute minimum on a closed interval will only occur
|
||||
at a critical point or an end point.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
## Rolle's theorem
|
||||
|
||||
Let $f(x)$ be differentiable on $(a,b)$ and continuous on
|
||||
@ -616,8 +601,8 @@ choices = [
|
||||
"``h(x) = f(x) - g(x)``",
|
||||
"``h(x) = f'(x) - g'(x)``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -630,8 +615,8 @@ L"It isn't. The function $f(x) = x^2$ has two zeros and $f''(x) = 2 > 0$",
|
||||
"By the Rolle's theorem, there is at least one, and perhaps more",
|
||||
L"By the mean value theorem, we must have $f'(b) - f'(a) > 0$ when ever $b > a$. This means $f'(x)$ is increasing and can't double back to have more than one zero."
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -645,8 +630,8 @@ choices = [
|
||||
"``c = 1 / (1/a + 1/b)``",
|
||||
"``c = a + (\\sqrt{5} - 1)/2 \\cdot (b-a)``"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -660,8 +645,8 @@ choices = [
|
||||
"``c = 1 / (1/a + 1/b)``",
|
||||
"``c = a + (\\sqrt{5} - 1)/2 \\cdot (b-a)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -678,8 +663,8 @@ Why is it known that $g(x)$ goes to $0$ as $x$ goes to zero (from the right)?
|
||||
choices = [L"The squeeze theorem applies, as $0 < g(x) < x$.",
|
||||
L"As $f(x)$ goes to zero by Rolle's theorem it must be that $g(x)$ goes to $0$.",
|
||||
L"This follows by the extreme value theorem, as there must be some $c$ in $[0,x]$."]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Since $g(x)$ goes to zero, why is it true that if $f(x)$ goes to $L$ as $x$ goes to zero that $f(g(x))$ must also have a limit $L$?
|
||||
@ -688,6 +673,6 @@ Since $g(x)$ goes to zero, why is it true that if $f(x)$ goes to $L$ as $x$ goes
|
||||
choices = ["It isn't true. The limit must be 0",
|
||||
L"The squeeze theorem applies, as $0 < g(x) < x$",
|
||||
"This follows from the limit rules for composition of functions"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -498,8 +498,8 @@ choices = [
|
||||
"The function oscillates too much to rely on the tangent line approximation far from the zero",
|
||||
"We can find an answer"
|
||||
]
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -525,6 +525,6 @@ choices = [
|
||||
"The function oscillates too much to rely on the tangent line approximations far from the zero",
|
||||
"We can find an answer"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
@ -14,7 +14,7 @@ using Roots
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
using ImplicitPlots
|
||||
|
||||
fig_size = (600, 400)
|
||||
fig_size = (800, 600)
|
||||
const frontmatter = (
|
||||
title = "Newton's method",
|
||||
description = "Calculus with Julia: Newton's method",
|
||||
@ -221,20 +221,15 @@ functions, convergence happens quickly.
|
||||
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
Newton looked at this same example in 1699 (B.T. Polyak, *Newton's
|
||||
method and its use in optimization*, European Journal of Operational
|
||||
Research. 02/2007; 181(3):1086-1096.) though his technique was
|
||||
slightly different as he did not use the derivative, *per se*, but
|
||||
rather an approximation based on the fact that his function was a
|
||||
polynomial (though identical to the derivative). Raphson (1690)
|
||||
proposed the general form, hence the usual name of the Newton-Raphson
|
||||
method.
|
||||
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Newton looked at this same example in 1699 (B.T. Polyak, *Newton's
|
||||
method and its use in optimization*, European Journal of Operational
|
||||
Research. 02/2007; 181(3):1086-1096.) though his technique was
|
||||
slightly different as he did not use the derivative, *per se*, but
|
||||
rather an approximation based on the fact that his function was a
|
||||
polynomial (though identical to the derivative). Raphson (1690)
|
||||
proposed the general form, hence the usual name of the Newton-Raphson
|
||||
method.
|
||||
|
||||
#### Examples
|
||||
|
||||
@ -634,13 +629,10 @@ This convergence to ``\alpha`` will be quadratic *if*:
|
||||
not necessarily a good approximation to the actual zero, $\alpha$.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The basic tradeoff: methods like Newton's are faster than the
|
||||
bisection method in terms of function calls, but are not guaranteed to
|
||||
converge, as the bisection method is.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The basic tradeoff: methods like Newton's are faster than the
|
||||
bisection method in terms of function calls, but are not guaranteed to
|
||||
converge, as the bisection method is.
|
||||
|
||||
|
||||
What can go wrong when one of these isn't the case is illustrated next:
|
||||
@ -802,8 +794,8 @@ If one step of Newton's method was used, what would be the value of $x_1$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``-2.224``", "``-2.80``", "``-0.020``", "``0.355``"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -827,8 +819,8 @@ L"It must be $x_1 > \alpha$",
|
||||
L"It must be $x_1 < x_0$",
|
||||
L"It must be $x_0 < x_1 < \alpha$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
----
|
||||
@ -852,8 +844,8 @@ L"It must be $x_1 < \alpha$",
|
||||
L"It must be $x_1 > x_0$",
|
||||
L"It must be $\alpha < x_1 < x_0$"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
----
|
||||
@ -866,8 +858,8 @@ L"As $f''(\xi)/2 \cdot(x-c)^2$ is non-negative, we must have $f(x) - (f(c) + f'(
|
||||
L"As $f''(\xi) < 0$ it must be that $f(x) - (f(c) + f'(c)\cdot(x-c)) \geq 0$.",
|
||||
L"This isn't true. The function $f(x) = x^3$ at $x=0$ provides a counterexample"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
This question can be used to give a proof for the previous two questions, which can be answered by considering the graphs alone. Combined, they say that if a function is increasing and concave up and ``\alpha`` is a zero, then if ``x_0 < \alpha`` it will be ``x_1 > \alpha``, and for any ``x_i > \alpha``, ``\alpha <= x_{i+1} <= x_\alpha``, so the sequence in Newton's method is decreasing and bounded below; conditions for which it is guaranteed mathematically there will be convergence.
|
||||
@ -1050,8 +1042,8 @@ choices = [
|
||||
"No. The initial guess is not close enough",
|
||||
"No. The second derivative is too big",
|
||||
L"No. The first derivative gets too close to $0$ for one of the $x_i$"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1067,8 +1059,8 @@ choices = [
|
||||
"No. The initial guess is not close enough",
|
||||
"No. The second derivative is too big, or does not exist",
|
||||
L"No. The first derivative gets too close to $0$ for one of the $x_i$"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1082,8 +1074,8 @@ choices = [
|
||||
"No. The initial guess is not close enough",
|
||||
"No. The second derivative is too big, or does not exist",
|
||||
L"No. The first derivative gets too close to $0$ for one of the $x_i$"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1097,8 +1089,8 @@ choices = [
|
||||
"No. The initial guess is not close enough",
|
||||
"No. The second derivative is too big, or does not exist",
|
||||
L"No. The first derivative gets too close to $0$ for one of the $x_i$"]
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1114,8 +1106,8 @@ choices = [
|
||||
"No. The initial guess is not close enough",
|
||||
"No. The second derivative is too big, or does not exist",
|
||||
L"No. The first derivative gets too close to $0$ for one of the $x_i$"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1177,8 +1169,8 @@ L"It doesn't fail, it converges to $0$",
|
||||
L"The tangent lines for $|x| > 0.25$ intersect at $x$ values with $|x| > 0.25$",
|
||||
L"The first derivative is $0$ at $1$"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1261,14 +1253,14 @@ So we have a means to find $y(x)$, but it is implicit.
|
||||
Using `find_zero`, find the value $x$ which maximizes `y` by finding a zero of `y'`. Use this to find the point $(x,y)$ with largest $y$ value.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
xstar = find_zero(yp, 0.5)
|
||||
xstar = find_zero(findy', 0.5)
|
||||
ystar = findy(xstar)
|
||||
choices = ["``(-0.57735, 1.15470)``",
|
||||
"``(0,0)``",
|
||||
"``(0, -0.57735)``",
|
||||
"``(0.57735, 0.57735)``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
(Using automatic derivatives works for values identified with `find_zero` *as long as* the initial point has its type the same as that of `x`.)
|
||||
|
||||
@ -210,13 +210,8 @@ fp = diff(f(x),x)
|
||||
fp, fp(c), f'(c), (f(c+h) - f(c))/h
|
||||
```
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
The use of `'` to find derivatives provided by `CalculusWithJulia` is convenient, and used extensively in these notes, but it needs to be noted that it does **not conform** with the generic meaning of `'` within `Julia`'s wider package ecosystem and may cause issue with linear algebra operations; the symbol is meant for the adjoint of a matrix.
|
||||
""")
|
||||
```
|
||||
|
||||
|
||||
!!! note
|
||||
The use of `'` to find derivatives provided by `CalculusWithJulia` is convenient, and used extensively in these notes, but it needs to be noted that it does **not conform** with the generic meaning of `'` within `Julia`'s wider package ecosystem and may cause issue with linear algebra operations; the symbol is meant for the adjoint of a matrix.
|
||||
|
||||
|
||||
## Questions
|
||||
|
||||
@ -12,11 +12,11 @@ using SymPy
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
fig_size = (400, 400)
|
||||
const frontmatter = (
|
||||
title = "Optimization",
|
||||
description = "Calculus with Julia: Optimization",
|
||||
tags = ["CalculusWithJulia", "derivatives", "optimization"],
|
||||
fig_size = (800, 600)
|
||||
frontmatter = (
|
||||
title = "Optimization",
|
||||
description = "Calculus with Julia: Optimization",
|
||||
tags = ["CalculusWithJulia", "derivatives", "optimization"],
|
||||
);
|
||||
|
||||
nothing
|
||||
@ -173,13 +173,8 @@ find_zeros(A', 0, 10) # find_zeros in `Roots`,
|
||||
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
|
||||
Look at the last definition of `A`. The function `A` appears on both sides, though on the left side with one argument and on the right with two. These are two "methods" of a *generic* function, `A`. `Julia` allows multiple definitions for the same name as long as the arguments (their number and type) can disambiguate which to use. In this instance, when one argument is passed in then the last defintion is used (`A(b,h(b))`), whereas if two are passed in, then the method that multiplies both arguments is used. The advantage of multiple dispatch is illustrated: the same concept - area - has one function name, though there may be different ways to compute the area, so there is more than one implementation.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Look at the last definition of `A`. The function `A` appears on both sides, though on the left side with one argument and on the right with two. These are two "methods" of a *generic* function, `A`. `Julia` allows multiple definitions for the same name as long as the arguments (their number and type) can disambiguate which to use. In this instance, when one argument is passed in then the last defintion is used (`A(b,h(b))`), whereas if two are passed in, then the method that multiplies both arguments is used. The advantage of multiple dispatch is illustrated: the same concept - area - has one function name, though there may be different ways to compute the area, so there is more than one implementation.
|
||||
|
||||
|
||||
#### Example: Norman windows
|
||||
@ -582,7 +577,7 @@ both positive. What value $x$ in $[0,L]$ will minimize the total travel time?
|
||||
We approach this symbolically with `SymPy`:
|
||||
|
||||
```julia;
|
||||
@syms a::positive b::positive L::positive r0::positive r1::positive
|
||||
@syms x::positive a::positive b::positive L::positive r0::positive r1::positive
|
||||
|
||||
d0 = sqrt(x^2 + a^2)
|
||||
d1 = sqrt((L-x)^2 + b^2)
|
||||
@ -913,8 +908,8 @@ choices = [
|
||||
"It is also 20",
|
||||
"``17.888``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1076,8 +1071,8 @@ Now if $Likhood(t) = \exp(-3t) \cdot \exp(-2t) \cdot \exp(-4t), \quad 0 \leq t \
|
||||
choices=["It does work and the answer is x = 2.27...",
|
||||
L" $Likhood(t)$ is not continuous on $0$ to $10$",
|
||||
L" $Likhood(t)$ takes its maximum at a boundary point - not a critical point"];
|
||||
ans = 3;
|
||||
radioq(choices, ans)
|
||||
answ = 3;
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
@ -1103,8 +1098,8 @@ choices=[
|
||||
"The median, or middle number, of the values",
|
||||
L"The square roots of the values squared, $(x_1^2 + \cdots x_n^2)^2$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1241,8 +1236,8 @@ choices = ["exactly four times",
|
||||
L"exactly $\pi$ times",
|
||||
L"about $2.6$ times as big",
|
||||
"about the same"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1278,8 +1273,8 @@ choices = [
|
||||
"``e/a``",
|
||||
"``a \\cdot e``"
|
||||
]
|
||||
ans=2
|
||||
radioq(choices, ans)
|
||||
answ=2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
@ -12,7 +12,7 @@ using SymPy
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
fig_size=(600, 400)
|
||||
fig_size=(800, 600)
|
||||
const frontmatter = (
|
||||
title = "Related rates",
|
||||
description = "Calculus with Julia: Related rates",
|
||||
@ -610,8 +610,8 @@ choices = [
|
||||
"The rate of change of price will increase",
|
||||
"The rate of change of price will be positive and will depend on the rate of change of excess demand."
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
(Theoretically, when demand exceeds supply, prices increase.)
|
||||
@ -625,8 +625,8 @@ choices = [
|
||||
"If the rate of change of unemployment is negative, the rate of change of wages will be negative.",
|
||||
"If the rate of change of unemployment is negative, the rate of change of wages will be positive."
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
(Colloquially, "the rate of change of unemployment is negative" means the unemployment rate is going down, so there are fewer workers available to fill new jobs.)
|
||||
@ -643,8 +643,8 @@ L"The rate of change of pressure is always increasing by $c$",
|
||||
"If volume is constant, the rate of change of pressure is proportional to the temperature",
|
||||
"If volume is constant, the rate of change of pressure is proportional to the rate of change of temperature",
|
||||
"If pressure is held constant, the rate of change of pressure is proportional to the rate of change of temperature"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -735,8 +735,8 @@ choices = [
|
||||
"``f(x) = x``",
|
||||
"``f(x) = x^2``"
|
||||
]
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -763,8 +763,8 @@ choices = [
|
||||
"``y = 1 - \\log(x)``",
|
||||
"``y = x(2x - 1/x)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
If $dx/dt = -1$, what is $dy/dt$?
|
||||
@ -776,6 +776,6 @@ choices = [
|
||||
"``dy/dt = -2x - 1/x``",
|
||||
"``dy/dt = 1``"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -14,7 +14,7 @@ using Unitful
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
using Roots
|
||||
|
||||
fig_size = (600, 400)
|
||||
fig_size = (800, 600)
|
||||
const frontmatter = (
|
||||
title = "Taylor Polynomials and other Approximating Polynomials",
|
||||
description = "Calculus with Julia: Taylor Polynomials and other Approximating Polynomials",
|
||||
@ -564,14 +564,9 @@ output. `SymPy` provides the `removeO` method to strip this. (It is called as `o
|
||||
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
!!! note
|
||||
A Taylor polynomial of degree ``n`` consists of ``n+1`` terms and an error term. The "Taylor series" is an *infinite* collection of terms, the first ``n+1`` matching the Taylor polynomial of degree ``n``. The fact that series are *infinite* means care must be taken when even talking about their existence, unlike a Tyalor polynomial, which is just a polynomial and exists as long as a sufficient number of derivatives are available.
|
||||
|
||||
A Taylor polynomial of degree ``n`` consists of ``n+1`` terms and an error term.
|
||||
The "Taylor series" is an *infinite* collection of terms, the first ``n+1`` matching the Taylor polynomial of degree ``n``. The fact that series are *infinite* means care must be taken when even talking about their existence, unlike a Tyalor polynomial, which is just a polynomial and exists as long as a sufficient number of derivatives are available.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
|
||||
We define a function to compute Taylor polynomials from a function. The following returns a function, not a symbolic object, using `D`, from `CalculusWithJulia`, which is based on `ForwardDiff.derivative`, to find higher-order derivatives:
|
||||
@ -965,8 +960,8 @@ choices = [
|
||||
"``\\sum_{k=0}^{4} (-1)^k/(2k+1)! \\cdot x^{2k+1}``",
|
||||
"``\\sum_{k=0}^{10} x^n/n!``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -980,8 +975,8 @@ choices = [
|
||||
"``\\sum_{k=0}^{4} (-1)^k/(2k+1)! \\cdot x^{2k+1}``",
|
||||
"``\\sum_{k=0}^{10} x^n/n!``"
|
||||
]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -997,8 +992,8 @@ choices = [
|
||||
"``\\sum_{k=0}^{4} (-1)^k/(2k+1)! \\cdot x^{2k+1}``",
|
||||
"``\\sum_{k=0}^{10} x^n/n!``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1012,8 +1007,8 @@ choices = [
|
||||
"``1/5!``",
|
||||
"``2/15``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1028,8 +1023,8 @@ choices = [
|
||||
"``x^2``",
|
||||
"``x^2 \\cdot (x - x^3/3! + x^5/5!)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1048,8 +1043,8 @@ If this is true, then formally evaluating at $x=0$ gives $f(0) = a$, so $a$ is d
|
||||
choices = ["``f''''(0) = e``",
|
||||
"``f''''(0) = 4 \\cdot 3 \\cdot 2 e = 4! e``",
|
||||
"``f''''(0) = 0``"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1069,8 +1064,8 @@ yesnoq(true)
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices =["It is increasing", "It is decreasing", "It both increases and decreases"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1078,8 +1073,8 @@ radioq(choices, ans)
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices=["A critical point", "An end point"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
* Which theorem tells you that for a *continuous* function over *closed* interval, a maximum value will exist?
|
||||
@ -1089,8 +1084,8 @@ choices = [
|
||||
"The intermediate value theorem",
|
||||
"The mean value theorem",
|
||||
"The extreme value theorem"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
* What is the *largest* possible value of the error:
|
||||
@ -1099,8 +1094,8 @@ radioq(choices, ans)
|
||||
choices = [
|
||||
"``1/6!\\cdot e^1 \\cdot 1^6``",
|
||||
"``1^6 \\cdot 1 \\cdot 1^6``"]
|
||||
ans = 1
|
||||
radioq(choices,ans)
|
||||
answ = 1
|
||||
radioq(choices,answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1115,8 +1110,8 @@ L"The function $e^x$ is increasing, so takes on its largest value at the endpoin
|
||||
L"The function has a critical point at $x=1/2$",
|
||||
L"The function is monotonic in $k$, so achieves its maximum at $k+1$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Assuming the above is right, find the smallest value $k$ guaranteeing a error no more than $10^{-16}$.
|
||||
|
||||
@ -12,10 +12,10 @@ using ForwardDiff
|
||||
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
const frontmatter = (
|
||||
title = "2D and 3D plots in Julia with Plots",
|
||||
description = "Calculus with Julia: 2D and 3D plots in Julia with Plots",
|
||||
tags = ["CalculusWithJulia", "differentiable_vector_calculus", "2d and 3d plots in julia with plots"],
|
||||
frontmatter = (
|
||||
title = "2D and 3D plots in Julia with Plots",
|
||||
description = "Calculus with Julia: 2D and 3D plots in Julia with Plots",
|
||||
tags = ["CalculusWithJulia", "differentiable_vector_calculus", "2d and 3d plots in julia with plots"],
|
||||
);
|
||||
nothing
|
||||
```
|
||||
@ -69,7 +69,8 @@ ts = range(0, 2pi, length=100)
|
||||
plot(unzip(r₂.(ts))...)
|
||||
```
|
||||
|
||||
As a convenience, `CalculusWithJulia` provides `plot_parametric` to produce this plot. The interval is specified with the `a..b` notation, the points to plot are adaptively chosen:
|
||||
|
||||
As a convenience, `CalculusWithJulia` provides `plot_parametric` to produce this plot. The interval is specified with the `a..b` notation of `IntervalSets` (which is available when the `CalculusWithJulia` package is loaded), the points to plot are adaptively chosen:
|
||||
|
||||
```julia
|
||||
plot_parametric(0..2pi, r₂) # interval first
|
||||
@ -340,7 +341,7 @@ surface(xs, ys, zs)
|
||||
note("The above may not work with all backends for `Plots`, even if those that support 3D graphics.")
|
||||
```
|
||||
|
||||
For convenience, the `plot_parametric` function from `CalculusWithJulia` can produce these plots using interval notation and a function:
|
||||
For convenience, the `plot_parametric` function from `CalculusWithJulia` can produce these plots using interval notation, `a..b`, and a function:
|
||||
|
||||
```julia; hold=true
|
||||
F(theta, phi) = [X(1, theta, phi), Y(1, theta, phi), Z(1, theta, phi)]
|
||||
|
||||
@ -13,7 +13,7 @@ using QuadGK
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
const frontmatter = (
|
||||
frontmatter = (
|
||||
title = "Polar Coordinates and Curves",
|
||||
description = "Calculus with Julia: Polar Coordinates and Curves",
|
||||
tags = ["CalculusWithJulia", "differentiable_vector_calculus", "polar coordinates and curves"],
|
||||
@ -143,7 +143,7 @@ rs = r.(ts)
|
||||
plot(ts, rs, proj=:polar, legend=false)
|
||||
```
|
||||
|
||||
To avoid having to create values for $\theta$ and values for $r$, the `CalculusWithJulia` package provides a helper function, `plot_polar`. To distinguish it from other functions provided by `Plots`, the calling pattern is different. It specifies an interval to plot over by `a..b` and puts that first, followed by `r`. Other keyword arguments are passed onto a `plot` call.
|
||||
To avoid having to create values for $\theta$ and values for $r$, the `CalculusWithJulia` package provides a helper function, `plot_polar`. To distinguish it from other functions provided by `Plots`, the calling pattern is different. It specifies an interval to plot over by `a..b` and puts that first (this notation for closed intervals is from `IntervalSets`), followed by `r`. Other keyword arguments are passed onto a `plot` call.
|
||||
|
||||
We will use this in the following, as the graphs are a bit more familiar and the calling pattern similar to how we have plotted functions.
|
||||
|
||||
@ -634,8 +634,8 @@ choices = [
|
||||
"a circle",
|
||||
"a line"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -649,8 +649,8 @@ choices = [
|
||||
"a circle",
|
||||
"a line"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -664,8 +664,8 @@ choices = [
|
||||
"a circle",
|
||||
"a line"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -681,8 +681,8 @@ choices = [
|
||||
"``\\pi/2``",
|
||||
"``1``"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
@ -10,6 +10,11 @@ using SymPy
|
||||
using Roots
|
||||
using QuadGK
|
||||
using JSON
|
||||
```
|
||||
|
||||
Also, these methods from the `Contour` package:
|
||||
|
||||
```julia
|
||||
import Contour: contours, levels, level, lines, coordinates
|
||||
```
|
||||
|
||||
@ -155,9 +160,8 @@ surface(xs, ys, 𝒇)
|
||||
|
||||
The `surface` function will generate the surface.
|
||||
|
||||
```julia; echo=false
|
||||
note("""Using `surface` as a function name is equivalent to `plot(xs, ys, f, seriestype=:surface)`.""")
|
||||
```
|
||||
!!! note
|
||||
Using `surface` as a function name is equivalent to `plot(xs, ys, f, seriestype=:surface)`.
|
||||
|
||||
We can also use `surface(xs, ys, zs)` where `zs` is not a vector, but
|
||||
rather a *matrix* of values corresponding to a grid described by the
|
||||
@ -548,7 +552,6 @@ r2₁(t) = [γ₁(t)..., 0]
|
||||
plot_parametric!(0..1/2, r2₁, linewidth=5, color=:black) # in the $x$-$y$ plane
|
||||
```
|
||||
|
||||
|
||||
The vector valued function `r3(t) = [γ(t)..., f(γ(t))]` takes the ``2``-dimensional path specified by $\vec\gamma(t)$ and adds a third, $x$, direction by composing the position with `f`. In this way, a ``2``-D path is visualized with a ``3``-D path. This viewpoint can be reversed, as desired.
|
||||
|
||||
However, the composition, $f\circ\vec\gamma$, is a univariate function, so this can also be visualized by
|
||||
@ -709,11 +712,8 @@ partial_x(f, y) = x -> ForwardDiff.derivative(u -> f(u,y), x)
|
||||
```
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
For vector-valued functions, we can overide the syntax `'` using `Base.adjoint`, as `'` is treated as a postfix operator in `Julia` for the `adjoint` operation. The symbol `\\nabla` is also available in `Julia`, but it is not an operator, so can't be used as mathematically written `∇f` (this could be used as a name though). In `CalculusWithJulia` a definition is made so essentially `∇(f) = x -> ForwardDiff.gradient(f, x)`. It does require parentheses to be called, as in `∇(f)`.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
For vector-valued functions, we can overide the syntax `'` using `Base.adjoint`, as `'` is treated as a postfix operator in `Julia` for the `adjoint` operation. The symbol `\\nabla` is also available in `Julia`, but it is not an operator, so can't be used as mathematically written `∇f` (this could be used as a name though). In `CalculusWithJulia` a definition is made so essentially `∇(f) = x -> ForwardDiff.gradient(f, x)`. It does require parentheses to be called, as in `∇(f)`.
|
||||
|
||||
|
||||
#### Symbolic expressions
|
||||
@ -1409,8 +1409,8 @@ From the graph, is the value of $f(1/2, 1)$ positive or negative?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["positive", "negative"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1421,8 +1421,8 @@ choices = [
|
||||
L"The line $x=0$",
|
||||
L"The line $y=0$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
Consider the contour plot
|
||||
@ -1449,8 +1449,8 @@ L"is around $(0.7, 0)$ and with a value less than $-0.4$",
|
||||
L"is around $(-2.0, 0)$ and with a value less than $-0.4$",
|
||||
L"is around $(2.0, 0)$ and with a value less than $-0.4$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
From this graph, where is the surface steeper?
|
||||
@ -1462,8 +1462,8 @@ L"near $(1/2, 0)$",
|
||||
L"near $(3/4, 0)$",
|
||||
L"near $(1, 0)$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1483,8 +1483,8 @@ choices = [
|
||||
L"Yes, the closed loops near $(-1.5, 0)$ and $(1.5, 0)$ will contain these",
|
||||
L"No, the vertical lines parallel to $x=0$ show this function to be flat"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Imagine hiking on this surface within this region. Could you traverse from left to right without having to go up or down?
|
||||
@ -1519,8 +1519,8 @@ choices = [
|
||||
"running essentially parallel to the contour lines",
|
||||
"running essentially perpendicular to the contour lines"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Why?
|
||||
@ -1530,8 +1530,8 @@ choices = [
|
||||
"By being essentially parallel, the steepness of the roadway can be kept to a passable level",
|
||||
"By being essentially perpendicular, the road can more quickly climb up the mountain"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
The pass is at about 2700 meters. As shown towards the top and bottom of the figure the contour lines show increasing heights, and to the left and right decreasing heights. The shape of the [pass](https://en.wikipedia.org/wiki/Mountain_pass) would look like:
|
||||
@ -1541,8 +1541,8 @@ choices = [
|
||||
"A saddle-like shape, called a *col* or *gap*",
|
||||
"A upside down bowl-like shape like the top of a mountain"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1561,8 +1561,8 @@ L"When $i(\vec{x}) = 0$",
|
||||
L"When any of $f(\vec{x})$, $g(\vec{x})$, or $i(\vec{x})$ are zero",
|
||||
L"The limit exists everywhere, as the function $f$, $g$, $h$, and $i$ have limits at $\vec{c}$ by assumption"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1602,8 +1602,8 @@ raw"`` \langle \cos(2y), \cos(y) \rangle``",
|
||||
raw"`` \langle \sin(x), \sin(2x) \rangle``",
|
||||
raw"`` \sin(x)\cos(2y)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Compute $f_y$
|
||||
@ -1615,8 +1615,8 @@ raw"`` \langle 2\sin(x), \sin(2x) \rangle``",
|
||||
raw"`` \langle -2\sin(2y), -\sin(y) \rangle``",
|
||||
raw"`` - \sin(2x)\sin(y)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1654,16 +1654,16 @@ The gradient is:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["two dimensional", "three dimensional"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
The surface is:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["two dimensional", "three dimensional"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
The gradient points in the direction of greatest increase of $f$. If a person were on a hill described by $z=f(x,y)$, what three dimensional vector would they follow to go the steepest way up the hill?
|
||||
@ -1674,8 +1674,8 @@ choices = [
|
||||
raw"`` \langle -f_x, -f_y, 1 \rangle``",
|
||||
raw"`` \langle f_x, f_y \rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
@ -1700,8 +1700,8 @@ choices = [
|
||||
raw"`` (f\circ\vec\gamma)(x,y)``",
|
||||
raw"`` \vec\gamma(x,y)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
A climber leaves base camp at $t_0$. At time $t > t_0$, what describes her elevation?
|
||||
@ -1712,8 +1712,8 @@ choices = [
|
||||
raw"`` \vec\gamma(t)``",
|
||||
raw"`` f(t)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
What does the vector-valued function $\vec{r}(t) = \langle x(t), y(t), (f\circ\vec\gamma(t))\rangle$ describe:
|
||||
@ -1723,8 +1723,8 @@ choices = [
|
||||
"The three dimensional position of the climber",
|
||||
"The climbers gradient, pointing in the direction of greatest ascent"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
In the figure, the climbers are making a switch back, so as to avoid the steeper direct ascent. Mathematically $\nabla{f}(\vec\gamma(t)) \cdot \vec\gamma'(t)$ describes the directional derivative that they follow. Using $\|\vec{u}\cdot\vec{v}\| = \|\vec{u}\|\|\vec{v}\|\cos(\theta)$, does this route:
|
||||
@ -1735,8 +1735,8 @@ choices = [
|
||||
L"Keep $\cos(\theta)$ as close to $1$ as possible, so the slope taken is as big as possible",
|
||||
L"Keep $̧\cos(\theta)$ as close to $0$ as possible, so that they climbers don't waste energy going up and down"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Suppose our climber reaches the top at time $t$. What would be $(f\circ\vec\gamma)'(t)$, assuming the derivative exists?
|
||||
@ -1747,8 +1747,8 @@ choices = [
|
||||
L"It would be $\langle f_x, f_y\rangle$ and point towards the sky, the direction of greatest ascent",
|
||||
"It would not exist, as there would not be enough oxygen to compute it"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1765,8 +1765,8 @@ raw"`` |\hat{T} \cdot \hat{P}| \leq \cos(π/18)``",
|
||||
raw"`` |\hat{T} \cdot \hat{P}| \leq \sin(\pi/18)``",
|
||||
raw"`` |\hat{T} \cdot \hat{P}| \leq \pi/18``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
The normal to the surface $z=f(x,y)$ is *not* the normal to the trail tread. Suppose $\vec{N}(t)$ is a function that returns this. At the same point $\vec\gamma(t)$, let $\vec{M} = \langle -f_x, -f_y, 0\rangle$ be a vector in 3 dimensions pointing downhill. Let "hats" indicate unit vectors. The outward slope is $\pi/2$ minus the angle between $\hat{N}$ and $\hat{M}$. What condition will ensure this angle is $5$ degrees ($\pi/36$ radians)?
|
||||
@ -1777,8 +1777,8 @@ choices = [
|
||||
raw"`` |\hat{N} \cdot \hat{M}| \leq \sin(\pi/2 - \pi/18)``",
|
||||
raw"`` |\hat{N} \cdot \hat{M}| \leq \pi/2 - \pi/18``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1797,8 +1797,8 @@ choices = [
|
||||
raw"`` 2 \cos{\left (3 \right )} - 7 \sin{\left (3 \right )}``",
|
||||
raw"`` 4 x^{2} y \sin{\left (x - y^{2} \right )} - x^{2} \sin{\left (x - y^{2} \right )} + 2 x \cos{\left (x - y^{2} \right )}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1813,8 +1813,8 @@ choices = [
|
||||
"Yes, by definition",
|
||||
L"No, not unless $\vec{v}$ were a unit vector"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1831,8 +1831,8 @@ choices = [
|
||||
raw"`` \langle 4x^3, 2z, 2y\rangle``",
|
||||
raw"`` \langle x^3 + 2x + 2x, 2y+ y^3, 2x\rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
The value of $\vec\gamma'(t)$ is:
|
||||
@ -1843,8 +1843,8 @@ choices = [
|
||||
raw"`` 1 + 2y + 3t^2``",
|
||||
raw"`` \langle 1,2, 3 \rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
The value of $(f\circ\vec\gamma)'(t)$ is found by:
|
||||
@ -1855,8 +1855,8 @@ choices = [
|
||||
L"Taking the dot product of $\nabla{f}(\vec\gamma'(t))$ and $\vec\gamma(t)$",
|
||||
L"Taking the dot product of $\nabla{f}(x,y,z)$ and $\vec\gamma'(t)$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1887,8 +1887,8 @@ choices = [
|
||||
"The green one",
|
||||
"The red one"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1915,8 +1915,8 @@ choices = [
|
||||
"The green one",
|
||||
"The red one"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1947,8 +1947,8 @@ choices = [
|
||||
L"Linear means $H$ is linear, so $g(\vec{x})$ describes a plane",
|
||||
L"Linear means $H$ is the $0$ matrix, so the gradient couldn't have been $\vec{0}$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Suppose, $H$ has the magic property that for *any* vector $\vec{v}^tH\vec{v} < 0$. What does this imply:
|
||||
@ -1959,8 +1959,8 @@ choices = [
|
||||
L"That $g(\vec{x}) = f(\vec{c})$",
|
||||
L"That $g(\vec{x}) \leq f(\vec{c})$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1974,8 +1974,8 @@ choices = [
|
||||
raw"`` \partial^4{f}/\partial{x^2}\partial{y^2}``",
|
||||
raw"`` \partial^4{f}/\partial{x^1}\partial{y^3}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1993,8 +1993,8 @@ choices = [
|
||||
raw"`` f_{yy}``"
|
||||
]
|
||||
x,y=1/2, 2
|
||||
val, ans = findmax([6x*y, 3x^2, 6*y, 6x, 0])
|
||||
radioq(choices, ans, keep_order=true)
|
||||
val, answ = findmax([6x*y, 3x^2, 6*y, 6x, 0])
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -2024,15 +2024,15 @@ Whereas,
|
||||
At $(0,0)$ what is $ \frac{\partial \frac{\partial f}{\partial x}}{ \partial y}$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = -1
|
||||
numericq(ans)
|
||||
answ = -1
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
At $(0,0)$ what is $ \frac{\partial \frac{\partial f}{\partial y}}{ \partial x}$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 1
|
||||
numericq(ans)
|
||||
answ = 1
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
Away from $(0,0)$ the mixed partial is $\frac{x^{6} + 9 x^{4} y^{2} - 9 x^{2} y^{4} - y^{6}}{x^{6} + 3 x^{4} y^{2} + 3 x^{2} y^{4} + y^{6}}$.
|
||||
@ -2043,8 +2043,8 @@ choices = [
|
||||
L"This is not continuous at $(0,0)$, still the limit along the two paths $x=0$ and $y=0$ are equivalent.",
|
||||
L"This is not continuous at $(0,0)$, as the limit along the two paths $x=0$ and $y=0$ are not equivalent."
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -2096,8 +2096,8 @@ L"The Burgers equation: $f_t + ff_x = f_{xx}$; describes waves at the beach whic
|
||||
L"The KdV equation: $f_t + 6ff_x+ f_{xxx} = 0$; models water waves in a narrow channel",
|
||||
L"The Schrodinger equation: $f_t = (i\hbar/(2m))f_xx$; used to describe a quantum particle of mass $m$"
|
||||
]
|
||||
ans′ = 3
|
||||
radioq(ode_choices, ans′, keep_order=true)
|
||||
answ′ = 3
|
||||
radioq(ode_choices, answ′, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -2106,8 +2106,8 @@ radioq(ode_choices, ans′, keep_order=true)
|
||||
What equation does the function $f(t, x) = sin(x-t) + sin(x+t)$ satisfy?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 1
|
||||
radioq(ode_choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(ode_choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -2116,14 +2116,14 @@ radioq(ode_choices, ans, keep_order=true)
|
||||
What equation does the function $f(t, x) = e^{-(x+t)^2}$ satisfy?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 4
|
||||
radioq(ode_choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(ode_choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
What equation does the function $f(x,y) = \cos(x) + \sin(y)$ satisfy?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 5
|
||||
radioq(ode_choices, ans, keep_order=true)
|
||||
answ = 5
|
||||
radioq(ode_choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
@ -8,6 +8,11 @@ using CalculusWithJulia
|
||||
using Plots
|
||||
using SymPy
|
||||
using Roots
|
||||
```
|
||||
|
||||
And the following from the `Contour` package:
|
||||
|
||||
```julia
|
||||
import Contour: contours, levels, level, lines, coordinates
|
||||
```
|
||||
|
||||
@ -109,8 +114,8 @@ pt = [a, b, 0]
|
||||
scatter!(unzip([pt])...)
|
||||
arrow!(pt, [1,0,0], linestyle=:dash)
|
||||
arrow!(pt, [0,1,0], linestyle=:dash)
|
||||
|
||||
```
|
||||
|
||||
#### Alternate forms
|
||||
|
||||
The equation for the tangent plane is often expressed in a more explicit form. For $n=2$, if we set $dx = x-a$ and $dy=y-a$, then the equation for the plane becomes:
|
||||
@ -915,8 +920,10 @@ Another might be the vertical squared distance to the line:
|
||||
|
||||
|
||||
```math
|
||||
d2(\alpha, \beta) = (y_1 - l(x_1))^2 + (y_2 - l(x_2))^2 + (y_3 - l(x_3))^2 =
|
||||
(y1 - (\alpha + \beta x_1))^2 + (y3 - (\alpha + \beta x_3))^2 + (y3 - (\alpha + \beta x_3))^2
|
||||
\begin{align*}
|
||||
d2(\alpha, \beta) &= (y_1 - l(x_1))^2 + (y_2 - l(x_2))^2 + (y_3 - l(x_3))^2 \\
|
||||
&= (y1 - (\alpha + \beta x_1))^2 + (y3 - (\alpha + \beta x_3))^2 + (y3 - (\alpha + \beta x_3))^2
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
Another might be the *shortest* distance to the line:
|
||||
@ -1011,8 +1018,8 @@ gammas₂ = [1.0]
|
||||
|
||||
for n in 1:5
|
||||
xn = xs₂[end]
|
||||
gamma = gammas₂[end]
|
||||
xn1 = xn - gamma * gradient(f₂)(xn)
|
||||
gamma₀ = gammas₂[end]
|
||||
xn1 = xn - gamma₀ * gradient(f₂)(xn)
|
||||
dx, dy = xn1 - xn, gradient(f₂)(xn1) - gradient(f₂)(xn)
|
||||
gamman1 = abs( (dx ⋅ dy) / (dy ⋅ dy) )
|
||||
|
||||
@ -1133,10 +1140,8 @@ fxx, d
|
||||
Consequently we have a local maximum at this critical point.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note(""" The `Optim.jl` package provides efficient implementations of these two numeric methods, and others. """)
|
||||
```
|
||||
|
||||
!!! note
|
||||
The `Optim.jl` package provides efficient implementations of these two numeric methods, and others.
|
||||
|
||||
## Constrained optimization, Lagrange multipliers
|
||||
|
||||
@ -1557,11 +1562,13 @@ This theorem can be generalized to scalar functions, but the notation can be cum
|
||||
Following [Folland](https://sites.math.washington.edu/~folland/Math425/taylor2.pdf) we use *multi-index* notation. Suppose $f:R^n \rightarrow R$, and let $\alpha=(\alpha_1, \alpha_2, \dots, \alpha_n)$. Then define the following notation:
|
||||
|
||||
```math
|
||||
|\alpha| = \alpha_1 + \cdots + \alpha_n, \quad
|
||||
\alpha! = \alpha_1!\alpha_2!\cdot\cdots\cdot\alpha_n!,\quad
|
||||
\vec{x}^\alpha = x_1^{\alpha_1}x_2^{\alpha_2}\cdots x_n^{\alpha^n}, \quad
|
||||
\partial^\alpha f = \partial_1^{\alpha_1}\partial_2^{\alpha_2}\cdots \partial_n^{\alpha_n} f =
|
||||
\frac{\partial^{|\alpha|}f}{\partial x_1^{\alpha_1} \partial x_2^{\alpha_2} \cdots \partial x_n^{\alpha_n}}.
|
||||
\begin{align*}
|
||||
|\alpha| &= \alpha_1 + \cdots + \alpha_n, \\
|
||||
\alpha! &= \alpha_1!\alpha_2!\cdot\cdots\cdot\alpha_n!, \\
|
||||
\vec{x}^\alpha &= x_1^{\alpha_1}x_2^{\alpha_2}\cdots x_n^{\alpha^n}, \\
|
||||
\partial^\alpha f &= \partial_1^{\alpha_1}\partial_2^{\alpha_2}\cdots \partial_n^{\alpha_n} f \\
|
||||
& = \frac{\partial^{|\alpha|}f}{\partial x_1^{\alpha_1} \partial x_2^{\alpha_2} \cdots \partial x_n^{\alpha_n}}.
|
||||
\endalign*}
|
||||
```
|
||||
|
||||
This notation makes many formulas from one dimension carry over to higher dimensions. For example, the binomial theorem says:
|
||||
@ -1781,8 +1788,8 @@ choices = [
|
||||
raw"`` 2x + y - 2z = 1``",
|
||||
raw"`` x + 2y + 3z = 6``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1798,8 +1805,8 @@ choices = [
|
||||
raw"`` y^2 + y, x^2 + x``",
|
||||
raw"`` \langle 2y + y^2, 2x + x^2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Is this the Hessian of $f$?
|
||||
@ -1830,8 +1837,8 @@ choices = [
|
||||
L"The function $f$ has a saddle point, as $d < 0$",
|
||||
L"Nothing can be said, as $d=0$"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1885,8 +1892,8 @@ choices = [
|
||||
L"Nothing can be said, as $d=0$",
|
||||
L"The test does not apply, as $\nabla{f}$ is not $0$ at this point."
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
Which is true of $f$ at $(0, -1/2)$:
|
||||
@ -1899,8 +1906,8 @@ choices = [
|
||||
L"Nothing can be said, as $d=0$",
|
||||
L"The test does not apply, as $\nabla{f}$ is not $0$ at this point."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1914,8 +1921,8 @@ choices = [
|
||||
L"Nothing can be said, as $d=0$",
|
||||
L"The test does not apply, as $\nabla{f}$ is not $0$ at this point."
|
||||
]
|
||||
ans = 5
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 5
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1962,8 +1969,8 @@ choices =[
|
||||
"It is the determinant of the Hessian",
|
||||
L"It isn't, $b^2-4ac$ is from the quadratic formula"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Which condition on $a$, $b$, and $c$ will ensure a *local maximum*:
|
||||
@ -1974,8 +1981,8 @@ choices = [
|
||||
L"That $a<0$ and $ac-b^2 > 0$",
|
||||
L"That $ac-b^2 < 0$"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
Which condition on $a$, $b$, and $c$ will ensure a saddle point?
|
||||
@ -1987,8 +1994,8 @@ choices = [
|
||||
L"That $a<0$ and $ac-b^2 > 0$",
|
||||
L"That $ac-b^2 < 0$"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -2016,8 +2023,8 @@ choices = [
|
||||
raw"`` \langle 2x, y^2\rangle``",
|
||||
raw"`` \langle x^2, 2y \rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Due to the form of the gradient of the constraint, finding when $\nabla{f} = \lambda \nabla{g}$ is the same as identifying when this ratio $|f_x/f_y|$ is $1$. The following solves for this by checking each point on the constraint:
|
||||
|
||||
@ -170,15 +170,12 @@ zs = [Z(theta, phi) for theta in thetas, phi in phis]
|
||||
surface(xs, ys, zs) ## see note
|
||||
```
|
||||
|
||||
```julis; echo=false
|
||||
note("""Only *some* backends for `Plots` will produce this type of plot. Both `plotly()` and `pyplot()` will, but not `gr()`.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Only *some* backends for `Plots` will produce this type of plot. Both `plotly()` and `pyplot()` will, but not `gr()`.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""Note: PyPlot can be used directly to make these surface plots: `import PyPlot; PyPlot.plot_surface(xs,ys,zs)`""")
|
||||
```
|
||||
!!! note
|
||||
PyPlot can be used directly to make these surface plots: `import PyPlot; PyPlot.plot_surface(xs,ys,zs).
|
||||
|
||||
Instead of the comprehension, broadcasting can be used
|
||||
|
||||
@ -856,8 +853,8 @@ choices = [
|
||||
"Yes",
|
||||
"No, it is the transpose"
|
||||
]
|
||||
ans=2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ=2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -879,8 +876,8 @@ choices = [
|
||||
"Yes",
|
||||
"No, it is the transpose"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ=1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -907,8 +904,8 @@ choices = [
|
||||
"The determinant of the Hessian.",
|
||||
"The determinant of the gradient."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -920,8 +917,8 @@ choices = [
|
||||
"`det(hessian(F(lambda, phi), [lambda, phi]))`",
|
||||
"`det(gradient(F(lambda, phi), [lambda, phi]))`"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ=1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -934,8 +931,8 @@ choices = [
|
||||
raw"`` 2x^3y/ (z\cos(z) + \sin(z) + 1)``",
|
||||
raw"`` 3x^2y^2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -949,8 +946,8 @@ choices = [
|
||||
raw"`` \frac{x \left(2 x^{2} - y^{2} z^{2}{\left (x,y \right )}\right)}{\left(x^{2} y^{2} - 2 z^{2}{\left (x,y \right )}\right) z{\left (x,y \right )}}``",
|
||||
raw"`` \frac{x \left(2 x^{2} - z^{2}{\left (x,y \right )}\right)}{\left(x^{2} - 2 z^{2}{\left (x,y \right )}\right) z{\left (x,y \right )}}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -965,8 +962,8 @@ choices = [
|
||||
raw"`` S/r``",
|
||||
raw"`` R``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Let $\phi = r^k$. What is $\nabla{\phi}$?
|
||||
@ -977,8 +974,8 @@ choices = [
|
||||
raw"`` kr^k R``",
|
||||
raw"`` k r^{k-2} S``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Based on your last answer, are all radial fields $R/r^n$, $n\geq 0$ gradients of scalar functions?
|
||||
@ -995,8 +992,8 @@ choices = [
|
||||
raw"`` S/r``",
|
||||
raw"`` S``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Express $S/r^n = \langle F_x, F_y\rangle$. For which $n$ is $\partial{F_y}/\partial{x} - \partial{F_x}/\partial{y} = 0$?
|
||||
@ -1008,8 +1005,8 @@ L"As the left-hand side becomes $(-n+2)r^{-n}$, only $n=2$.",
|
||||
L"All $n \geq 0$",
|
||||
L"No values of $n$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
(The latter is of interest, as only when the expression is $0$ will the vector field be the gradient of a scalar function.)
|
||||
|
||||
@ -7,20 +7,26 @@ using CalculusWithJulia
|
||||
using Plots
|
||||
using SymPy
|
||||
using Roots
|
||||
using DifferentialEquations
|
||||
using LinearAlgebra
|
||||
using QuadGK
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```julia
|
||||
import DifferentialEquations
|
||||
import DifferentialEquations: ODEProblem, Tsit5
|
||||
```
|
||||
|
||||
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
const frontmatter = (
|
||||
title = "Vector-valued functions, ``f:R \\rightarrow R^n``",
|
||||
description = "Calculus with Julia: Vector-valued functions, ``f:R \\rightarrow R^n``",
|
||||
tags = ["CalculusWithJulia", "differentiable_vector_calculus", "vector-valued functions, ``f:R \\rightarrow r^n``"],
|
||||
frontmatter = (
|
||||
title = "Vector-valued functions, ``f:R \\rightarrow R^n``",
|
||||
description = "Calculus with Julia: Vector-valued functions, ``f:R \\rightarrow R^n``",
|
||||
tags = ["CalculusWithJulia", "differentiable_vector_calculus", "vector-valued functions, ``f:R \\rightarrow r^n``"],
|
||||
);
|
||||
|
||||
import PlutoUI
|
||||
nothing
|
||||
```
|
||||
|
||||
@ -150,7 +156,6 @@ ts = range(0, 6pi, length=200)
|
||||
plot(unzip(g.(ts))..., camera=(0, 90))
|
||||
```
|
||||
|
||||
|
||||
The graph of $h$ shows that this function parameterizes a line in space. The line segment for $-2 \leq t \leq 2$ is shown below:
|
||||
|
||||
```julia; hold=true
|
||||
@ -163,18 +168,17 @@ plot(unzip(h.(ts))...)
|
||||
While the `unzip` function is easy to understand as a function that reshapes data from one format into one that `plot` can use, it's usage is a bit cumbersome.
|
||||
The `CalculusWithJulia` package provides a function `plot_parametric` which hides the use of `unzip` and the splatting within a function definition.
|
||||
|
||||
The function borrows a calling style for `Makie`. The interval to plot over is specified first using `a..b` notation (from `IntervalSets`), then the function is specified. Additional keyword arguments are passed along to `plot`.
|
||||
The function borrows a calling style for `Makie`. The interval to plot
|
||||
over is specified first using `a..b` notation (which specifies a
|
||||
closed interval in the `IntervalSets` package), then the function is
|
||||
specified. Additional keyword arguments are passed along to `plot`.
|
||||
|
||||
```julia;
|
||||
plot_parametric(-2..2, h)
|
||||
```
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
Defining plotting functions in `Julia` for `Plots` is facilitated by the `RecipesBase` package. There are two common choices: creating a new function for plotting, as is done with `plot_parametric` and `plot_polar`; or creating a new type so that `plot` can dispatch to an appropriate plotting method. The latter would also be a reasonable choice, but wasn't taken here. In any case, each can be avoided by creating the appropriate values for `xs` and `ys` (and possibly `zs`).
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Defining plotting functions in `Julia` for `Plots` is facilitated by the `RecipesBase` package. There are two common choices: creating a new function for plotting, as is done with `plot_parametric` and `plot_polar`; or creating a new type so that `plot` can dispatch to an appropriate plotting method. The latter would also be a reasonable choice, but wasn't taken here. In any case, each can be avoided by creating the appropriate values for `xs` and `ys` (and possibly `zs`).
|
||||
|
||||
##### Example
|
||||
|
||||
@ -313,76 +317,83 @@ In 1935 [Marcel Duchamp](https://arthur.io/art/marcel-duchamp/rotorelief-no-10-c
|
||||
* each nested circle is drawn after its center is rotated by ``\theta`` radian;
|
||||
* an animation captures the movement for display.
|
||||
|
||||
```julia; hold=true;
|
||||
```julia
|
||||
let
|
||||
# https://exploratorium.tumblr.com/post/33140874462/marcel-duchamp-rotoreliefs-duchamp-recognized
|
||||
|
||||
# coordinates and colors selected by gimp from
|
||||
# https://arthur.io/art/marcel-duchamp/rotorelief-no-10-cage-modele-depose-verso
|
||||
circs = [466 548 513 505 556 554 # x₁,y₁,x₂,y₂,x₂,y₃
|
||||
414 549 511 455 595 549
|
||||
365 545 507 408 635 548
|
||||
319 541 506 361 673 546
|
||||
277 543 509 317 711 546
|
||||
236 539 507 272 747 551
|
||||
201 541 504 230 781 550
|
||||
166 541 503 189 816 544
|
||||
140 542 499 153 848 538
|
||||
116 537 496 119 879 538
|
||||
96 539 501 90 905 534
|
||||
81 530 500 67 930 530
|
||||
72 525 498 51 949 529
|
||||
66 520 500 36 966 527
|
||||
60 515 499 25 982 526
|
||||
35 509 499 11 1004 525 # outer edge, c₀
|
||||
]
|
||||
circs = [466 548 513 505 556 554 # x₁,y₁,x₂,y₂,x₂,y₃
|
||||
414 549 511 455 595 549
|
||||
365 545 507 408 635 548
|
||||
319 541 506 361 673 546
|
||||
277 543 509 317 711 546
|
||||
236 539 507 272 747 551
|
||||
201 541 504 230 781 550
|
||||
166 541 503 189 816 544
|
||||
140 542 499 153 848 538
|
||||
116 537 496 119 879 538
|
||||
96 539 501 90 905 534
|
||||
81 530 500 67 930 530
|
||||
72 525 498 51 949 529
|
||||
66 520 500 36 966 527
|
||||
60 515 499 25 982 526
|
||||
35 509 499 11 1004 525 # outer edge, c₀
|
||||
]
|
||||
|
||||
greenblue= RGB(8/100, 58/100, 53/100)
|
||||
grey = RGB(76/100, 74/100, 72/100)
|
||||
white = RGB(88/100, 85/100, 81/100)
|
||||
greenblue= RGB(8/100, 58/100, 53/100)
|
||||
grey = RGB(76/100, 74/100, 72/100)
|
||||
white = RGB(88/100, 85/100, 81/100)
|
||||
|
||||
# solve for center of circle, radius for each
|
||||
@syms h::positive k::positive r::positive
|
||||
function solve_i(i)
|
||||
eqs = [(p[1] - h)^2 + (p[2]-k)^2 ~ r^2 for
|
||||
p ∈ (circs[i,1:2], circs[i,3:4], circs[i,5:6])]
|
||||
d = solve(eqs)[1]
|
||||
(x=float(d[h]), y=float(d[k]), r=float(d[r]))
|
||||
end
|
||||
c₀, cs... = solve_i.(16:-1:1) # c₀ is centered
|
||||
# solve for center of circle, radius for each
|
||||
@syms h::positive k::positive r::positive
|
||||
function solve_i(i)
|
||||
eqs = [(p[1] - h)^2 + (p[2]-k)^2 ~ r^2 for
|
||||
p ∈ (circs[i,1:2], circs[i,3:4], circs[i,5:6])]
|
||||
d = solve(eqs)[1]
|
||||
(x=float(d[h]), y=float(d[k]), r=float(d[r]))
|
||||
end
|
||||
c₀, cs... = solve_i.(16:-1:1) # c₀ is centered
|
||||
|
||||
function duchamp_rotorelief_10(θ)
|
||||
p = plot(legend=false,
|
||||
axis=nothing, xaxis=false, yaxis=false,
|
||||
aspect_ratio=:equal)
|
||||
function duchamp_rotorelief_10(θ)
|
||||
p = plot(legend=false,
|
||||
axis=nothing, xaxis=false, yaxis=false,
|
||||
aspect_ratio=:equal)
|
||||
|
||||
O = [c₀.x, c₀.y]
|
||||
θ̂ = [cos(θ), sin(θ)]
|
||||
O = [c₀.x, c₀.y]
|
||||
θ̂ = [cos(θ), sin(θ)]
|
||||
|
||||
circle!(O, c₀.r, # outer ring is c₀
|
||||
linewidth=2,
|
||||
color=grey, fill=white,
|
||||
seriestype=:shape)
|
||||
circle!(O, c₀.r, # outer ring is c₀
|
||||
linewidth=2,
|
||||
color=grey, fill=white,
|
||||
seriestype=:shape)
|
||||
|
||||
for (i,c) ∈ enumerate(cs) # add nested rings
|
||||
rᵢ = sqrt((c₀.x - c.x)^2+(c₀.y - c.y)^2)
|
||||
P = O + rᵢ * θ̂ # rotate about origin by θ
|
||||
circle!(P, c.r,
|
||||
linewidth = i == 1 ? 1 : i <= 3 ? 2 : 3,
|
||||
color=greenblue)
|
||||
end
|
||||
|
||||
p
|
||||
|
||||
for (i,c) ∈ enumerate(cs) # add nested rings
|
||||
rᵢ = sqrt((c₀.x - c.x)^2+(c₀.y - c.y)^2)
|
||||
P = O + rᵢ * θ̂ # rotate about origin by θ
|
||||
circle!(P, c.r,
|
||||
linewidth = i == 1 ? 1 : i <= 3 ? 2 : 3,
|
||||
color=greenblue)
|
||||
end
|
||||
|
||||
p
|
||||
# animate using Plots.@animate macro
|
||||
anim = @animate for θ ∈ range(0, -2π, length=60)
|
||||
duchamp_rotorelief_10(θ)
|
||||
end
|
||||
|
||||
fname = tempname() * ".gif"
|
||||
gif(anim, fname, fps = 40)
|
||||
end
|
||||
```
|
||||
|
||||
# animate using Plots.@animate macro
|
||||
anim = @animate for θ ∈ range(0, -2π, length=60)
|
||||
duchamp_rotorelief_10(θ)
|
||||
end
|
||||
|
||||
fname = tempname() * ".gif"
|
||||
gif(anim, fname, fps = 40)
|
||||
PlutoUI.LocalResource(fname) # to display w/in Pluto
|
||||
```julia; echo=false
|
||||
#import PlutoUI
|
||||
#PlutoUI.LocalResource(fname) # to display w/in Pluto
|
||||
nothing
|
||||
```
|
||||
|
||||
##### Example
|
||||
@ -1279,6 +1290,7 @@ ts = range(t_span..., length=1001)
|
||||
surface(unzip(r_0.(ts, θs'))...)
|
||||
```
|
||||
|
||||
|
||||
## Arc length
|
||||
|
||||
In [Arc length](../integrals/arc_length.html) there is a discussion of how to find the arc length of a parameterized curve in ``2`` dimensions. The general case is discussed by [Destafano](https://randomproofs.files.wordpress.com/2010/11/arc_length.pdf) who shows:
|
||||
@ -1456,7 +1468,8 @@ Here, when $b$ gets large, the curve looks more and more "straight" and the tors
|
||||
|
||||
[Levi and Tabachnikov](https://projecteuclid.org/download/pdf_1/euclid.em/1259158427) consider the trajectories of the front and rear bicycle wheels. Recall the notation previously used: $\vec{F}(t)$ for the front wheel, and $\vec{B}(t)$ for the rear wheel trajectories. Consider now their parameterization by arc length, using $u$ for the arc-length parameter for $\vec{F}$ and $v$ for $\vec{B}$. We define $\alpha(u)$ to be the steering angle of the bicycle. This can be found as the angle between the tangent vector of the path of $\vec{F}$ with the vector $\vec{B} - \vec{F}$. Let $\kappa$ be the curvature of the front wheel and $k$ the curvature of the back wheel.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
```julia; echo=false
|
||||
let
|
||||
a = 1
|
||||
F(t) = [cos(pi/2 - t), 2sin(pi/2-t)]
|
||||
p = (a, F)
|
||||
@ -1486,6 +1499,7 @@ annotate!([(-.5,1.5,L"k"),
|
||||
(.85, 1.3, L"\alpha")])
|
||||
|
||||
plt
|
||||
end
|
||||
```
|
||||
|
||||
Levi and Tabachnikov prove in their Proposition 2.4:
|
||||
@ -1510,10 +1524,12 @@ when a curve is parameterized by arc length, the curvature is more directly comp
|
||||
The tangent vector is of unit length, when parametrized by arc length. This implies its derivative will be orthogonal. If $\vec{r}(t)$ is a parameterization by arc length, then the curvature formula simplifies as:
|
||||
|
||||
```math
|
||||
\kappa(s) = \frac{\| \vec{r}'(s) \times \vec{r}''(s) \|}{\|\vec{r}'(s)\|^3} =
|
||||
\frac{\| \vec{r}'(s) \times \vec{r}''(s) \|}{1} =
|
||||
\| \vec{r}'(s) \| \| \vec{r}''(s) \| \sin(\theta) =
|
||||
1 \| \vec{r}''(s) \| 1 = \| \vec{r}''(s) \|.
|
||||
\begin{align*}
|
||||
\kappa(s) &= \frac{\| \vec{r}'(s) \times \vec{r}''(s) \|}{\|\vec{r}'(s)\|^3} \\
|
||||
&= \frac{\| \vec{r}'(s) \times \vec{r}''(s) \|}{1} \\
|
||||
&= \| \vec{r}'(s) \| \| \vec{r}''(s) \| \sin(\theta) \\
|
||||
&= 1 \| \vec{r}''(s) \| 1 = \| \vec{r}''(s) \|.
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
|
||||
@ -1867,24 +1883,27 @@ Let ``r`` be the radius of a circle and for concreteness we position it at ``(-r
|
||||
* Between angles ``\pi/2`` and until the horse's ``y`` position is ``0`` when the tether is taut the boundary of what can be eaten is described by the involute.
|
||||
* The horse can't eat from withing the circle or radius ``r``.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
r,R = 1, 10
|
||||
R = max(R, pi*r) # R ≥ 1/2 circumference
|
||||
```julia; echo=false
|
||||
let
|
||||
r,R = 1, 10
|
||||
R = max(R, pi*r) # R ≥ 1/2 circumference
|
||||
|
||||
γ(θ) = -2r*cos(θ) * [cos(θ), sin(θ)] # parameterize the circle of radius r
|
||||
involute(t) = γ(t) + γ'(t)/norm(γ'(t))* (R - quadgk(u -> norm(γ'(u)), pi/2, t)[1])
|
||||
t₀ = find_zero(t -> round(involute(t)[2], digits=4), (3pi/4, pi))
|
||||
γ(θ) = -2r*cos(θ) * [cos(θ), sin(θ)] # parameterize the circle of radius r
|
||||
involute(t) = γ(t) + γ'(t)/norm(γ'(t))* (R - quadgk(u -> norm(γ'(u)), pi/2, t)[1])
|
||||
t₀ = find_zero(t -> round(involute(t)[2], digits=4), (3pi/4, pi))
|
||||
|
||||
p = plot(; legend=false)
|
||||
plot_polar!(0..(pi/2), t -> R) # unobstructed -> quarter circle
|
||||
plot_parametric!((pi/2)..t₀, involute)
|
||||
plot_parametric!((pi/2)..pi, γ)
|
||||
plot!([0,R],[0,0])
|
||||
p = plot(; legend=false)
|
||||
plot_polar!(0..(pi/2), t -> R) # unobstructed -> quarter circle
|
||||
plot_parametric!((pi/2)..t₀, involute)
|
||||
plot_parametric!((pi/2)..pi, γ)
|
||||
plot!([0,R],[0,0])
|
||||
end
|
||||
```
|
||||
|
||||
To solve for the area we parameterize the circle of radius ``r`` between ``\pi/2`` and when the involute would cross the ``x`` axis. We use `find_zero` to identify the value.
|
||||
|
||||
```julia; hold=true
|
||||
```julia
|
||||
let
|
||||
r,R = 160/(2π), 160
|
||||
R = max(R, pi*r) # R ≥ 1/2 circumference
|
||||
γ(θ) = -2r*cos(θ) * [cos(θ), sin(θ)]
|
||||
@ -1899,6 +1918,7 @@ x′(t) = (h=1e-4; (involute(t+h)[1]-involute(t-h)[1])/(2h))
|
||||
A₂ = quadgk(t -> -y(t)*x′(t), pi/2, t₀)[1] # A₂ = -∫ y dx, as counterclockwise parameterization
|
||||
A₃ = (1/2) * π * r^2
|
||||
2 * (A₁ + A₂ - A₃)
|
||||
end
|
||||
```
|
||||
|
||||
The calculation for ``A_1`` and ``A_3`` are from the familiar formula for the area of a circle. However, ``A_2`` requires the formula for area above the ``x`` axis when the curve is parameterized: ``A = -\int_a^b y(t) x'(t) dt``, given how the curve is parameterized. As written, the automatic derivative of the numeric integral gives an error, so a central-difference approximation is used for ``x'(t)``.
|
||||
@ -1920,8 +1940,8 @@ choices = [
|
||||
q"[0.0782914, 0.292893 ]",
|
||||
q"[0.181172, 0.5]",
|
||||
q"[0.570796, 1.0]"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
And the position at $\pi/2$?
|
||||
@ -1932,8 +1952,8 @@ choices = [
|
||||
q"[0.0782914, 0.292893 ]",
|
||||
q"[0.181172, 0.5]",
|
||||
q"[0.570796, 1.0]"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1946,8 +1966,8 @@ choices = [
|
||||
" ``\\langle Rt - R\\sin(t),~ R - R\\cos(t) \\rangle``",
|
||||
" ``\\langle -r\\sin(t),~ -r\\cos(t) \\rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1961,8 +1981,8 @@ choices = [
|
||||
" ``1 - \\cos(t)``",
|
||||
" ``1 + \\cos(t) + \\cos(2t)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1995,8 +2015,8 @@ q"[1,1]",
|
||||
q"[2,0]",
|
||||
q"[0,0]"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
What is the derivative at $t=\pi$?
|
||||
@ -2008,8 +2028,8 @@ q"[1,1]",
|
||||
q"[2,0]",
|
||||
q"[0,0]"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -2023,8 +2043,8 @@ choices = [
|
||||
" ``R``",
|
||||
" ``R^2``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -2053,8 +2073,8 @@ choices = [
|
||||
" ``1``",
|
||||
" ``t + t^2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Numerically find the arc length.
|
||||
@ -2089,8 +2109,8 @@ choices = [
|
||||
"greater than the curvature at ``t=0``",
|
||||
"less than the curvature at ``t=0``",
|
||||
"the same as the curvature at ``t=0``"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
The curvature as $t\rightarrow \infty$ will be
|
||||
@ -2101,8 +2121,8 @@ choices = [
|
||||
" ``\\infty``",
|
||||
" ``1``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
----
|
||||
@ -2116,8 +2136,8 @@ choices = [
|
||||
" ``2``",
|
||||
" ``1``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -2132,8 +2152,8 @@ x0 = [0,0,5]
|
||||
v0 = [120, -2, 2]
|
||||
a = [0, 16, -32]
|
||||
r(t) = x0 + v0*t + 1/2*a*t^2
|
||||
ans = 60/v0[1]
|
||||
numericq(ans)
|
||||
answ = 60/v0[1]
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
At $t=1/4$ the ball is half-way to home. If the batter reads the ball at this point, where in the $y$ direction is the ball?
|
||||
@ -2144,8 +2164,8 @@ v0 = [120, -2, 2]
|
||||
a = [0, 16, -32]
|
||||
r(t) = x0 + v0*t + 1/2*a*t^2
|
||||
t = 1/4
|
||||
ans = r(t)[2]
|
||||
numericq(ans)
|
||||
answ = r(t)[2]
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
At $t=1/2$ has the ball moved more than ``1/2`` foot in the $y$ direction?
|
||||
@ -2156,8 +2176,8 @@ v0 = [120, -2, 2]
|
||||
a = [0, 16, -32]
|
||||
r(t) = x0 + v0*t + 1/2*a*t^2
|
||||
t = 1/2
|
||||
ans = abs(r(t)[2]) > 1/2
|
||||
yesnoq(ans)
|
||||
answ = abs(r(t)[2]) > 1/2
|
||||
yesnoq(answ)
|
||||
```
|
||||
|
||||
|
||||
@ -2201,8 +2221,8 @@ choices = [
|
||||
" ``2\\tan(\\theta)``",
|
||||
" ``\\tan(\\theta)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Using the polar form of a circle, the length between the origin and $B$ is given by $2\cos(\theta-\pi/2) = 2\sin(\theta)$. Using this, what is the $y$ coordinate of $B$?
|
||||
@ -2214,8 +2234,8 @@ choices = [
|
||||
" ``2``",
|
||||
" ``\\sin(\\theta)``"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -2229,8 +2249,8 @@ choices = [
|
||||
" ``t^n + t^{n+1}``",
|
||||
" ``\\sqrt{n^2 + t^2}``"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
For $n=2$, the arc length of $\vec{r}$ can be found exactly. What is the arc-length between $0 \leq t \leq a$?
|
||||
@ -2241,8 +2261,8 @@ choices = [
|
||||
" ``\\frac{2 a^{\\frac{5}{2}}}{5}``",
|
||||
" ``\\sqrt{a^2 + 4}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -2257,30 +2277,32 @@ choices = [
|
||||
" ``\\pi/2``",
|
||||
" ``2``"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
###### Question
|
||||
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
t0, t1 = pi/12, pi/3
|
||||
tspan = (t0, t1) # time span to consider
|
||||
```julia; echo=false
|
||||
let
|
||||
t0, t1 = pi/12, pi/3
|
||||
tspan = (t0, t1) # time span to consider
|
||||
|
||||
a = 1
|
||||
r(theta) = -cos(theta) + 4*2cos(theta)*sin(theta)^2
|
||||
F(t) = r(t) * [cos(t), sin(t)]
|
||||
p = (a, F) # combine parameters
|
||||
a = 1
|
||||
r(theta) = -cos(theta) + 4*2cos(theta)*sin(theta)^2
|
||||
F(t) = r(t) * [cos(t), sin(t)]
|
||||
p = (a, F) # combine parameters
|
||||
|
||||
B0 = F(0) - [0, a] # some initial position for the back
|
||||
prob = ODEProblem(bicycle, B0, tspan, p)
|
||||
B0 = F(0) - [0, a] # some initial position for the back
|
||||
prob = ODEProblem(bicycle, B0, tspan, p)
|
||||
|
||||
out = solve(prob, reltol=1e-6, Tsit5())
|
||||
out = solve(prob, reltol=1e-6, Tsit5())
|
||||
|
||||
plt = plot(unzip(F, t0, t1)..., legend=false, color=:red)
|
||||
plot!(plt, unzip(t->out(t), t0, t1)..., color=:blue)
|
||||
plt = plot(unzip(F, t0, t1)..., legend=false, color=:red)
|
||||
plot!(plt, unzip(t->out(t), t0, t1)..., color=:blue)
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
@ -2291,8 +2313,8 @@ choices = [
|
||||
"The front wheel",
|
||||
"The back wheel"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -2300,22 +2322,24 @@ radioq(choices, ans)
|
||||
###### Question
|
||||
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
t0, t1 = 0.0, pi/3
|
||||
tspan = (t0, t1) # time span to consider
|
||||
```julia; echo=false
|
||||
let
|
||||
t0, t1 = 0.0, pi/3
|
||||
tspan = (t0, t1) # time span to consider
|
||||
|
||||
a = 1
|
||||
r(t) = 3a * cos(2t)cos(t)
|
||||
F(t) = r(t) * [cos(t), sin(t)]
|
||||
p = (a, F) # combine parameters
|
||||
a = 1
|
||||
r(t) = 3a * cos(2t)cos(t)
|
||||
F(t) = r(t) * [cos(t), sin(t)]
|
||||
p = (a, F) # combine parameters
|
||||
|
||||
B0 = F(0) - [0, a] # some initial position for the back
|
||||
prob = ODEProblem(bicycle, B0, tspan, p)
|
||||
B0 = F(0) - [0, a] # some initial position for the back
|
||||
prob = ODEProblem(bicycle, B0, tspan, p)
|
||||
|
||||
out = solve(prob, reltol=1e-6, Tsit5())
|
||||
out = solve(prob, reltol=1e-6, Tsit5())
|
||||
|
||||
plt = plot(unzip(F, t0, t1)..., legend=false, color=:blue)
|
||||
plot!(plt, unzip(t->out(t), t0, t1)..., color=:red)
|
||||
plt = plot(unzip(F, t0, t1)..., legend=false, color=:blue)
|
||||
plot!(plt, unzip(t->out(t), t0, t1)..., color=:red)
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
@ -2326,8 +2350,8 @@ choices = [
|
||||
"The front wheel",
|
||||
"The back wheel"
|
||||
]
|
||||
ans=2
|
||||
radioq(choices, ans)
|
||||
answ=2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -2357,8 +2381,8 @@ If a car is on a straight road, then $\kappa=0$. Is the acceleration along the $
|
||||
choices = [
|
||||
"The ``\\hat{T}`` direction",
|
||||
"The ``\\hat{N}`` direction"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Suppose no gas or brake is applied for a duration of time. The tangential acceleration will be $0$. During this time, which of these must be $0$?
|
||||
@ -2369,8 +2393,8 @@ choices = [
|
||||
" ``ds/dt``",
|
||||
" ``d^2s/dt^2``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
In going around a corner (with non-zero curvature), which is true?
|
||||
@ -2381,8 +2405,8 @@ choices = [
|
||||
"The acceleration in the normal direction depends only on the curvature and not the speed (``ds/dt``)",
|
||||
"The acceleration in the normal direction depends only on the speed (``ds/dt``) and not the curvature"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -2409,8 +2433,8 @@ choices = [
|
||||
" ``1 + 2t``",
|
||||
" ``1 - 2t``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
* Compute $k(t)$
|
||||
@ -2422,8 +2446,8 @@ choices = [
|
||||
" ``8t``",
|
||||
" ``-8t``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
* Compute $X(t)$
|
||||
@ -2435,8 +2459,8 @@ choices = [
|
||||
" ``t - 2(8t)/(1-2t)``",
|
||||
" ``t - 1(1+4t^2)/2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
* Compute $Y(t)$
|
||||
@ -2448,8 +2472,8 @@ choices = [
|
||||
" ``t^2 - 1(1+4t^2)/2``",
|
||||
" ``t^2 - 2t(1+4t^2)/2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -2477,6 +2501,6 @@ choices = [
|
||||
"An ellipse of the form ``\\langle a\\cos(t), b\\sin(t)``",
|
||||
"A cyloid of the form ``c\\langle t + \\sin(t), 1 - \\cos(t)\\rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -363,9 +363,9 @@ Starting with three vectors, we can create three orthogonal vectors using projec
|
||||
Let's begin with three vectors in $R^3$:
|
||||
|
||||
```julia;
|
||||
u⃗ = [1, 2, 3]
|
||||
v⃗ = [1, 1, 2]
|
||||
w⃗ = [1, 2, 4]
|
||||
u = [1, 2, 3]
|
||||
v = [1, 1, 2]
|
||||
w = [1, 2, 4]
|
||||
```
|
||||
|
||||
We can find a vector from `v` orthogonal to `u` using:
|
||||
@ -374,14 +374,14 @@ We can find a vector from `v` orthogonal to `u` using:
|
||||
unit_vec(u) = u / norm(u)
|
||||
projection(u, v) = (u ⋅ unit_vec(v)) * unit_vec(v)
|
||||
|
||||
v⃗⟂ = v⃗ - projection(v⃗, u⃗)
|
||||
w⃗⟂ = w⃗ - projection(w⃗, u⃗) - projection(w⃗, v⃗⟂)
|
||||
vₚ = v - projection(v, u)
|
||||
wₚ = w - projection(w, u) - projection(w, vₚ)
|
||||
```
|
||||
|
||||
We can verify the orthogonality through:
|
||||
|
||||
```julia;
|
||||
u⃗ ⋅ v⃗⟂, u⃗ ⋅ w⃗⟂, v⃗⟂ ⋅ w⃗⟂
|
||||
u ⋅ vₚ, u ⋅ wₚ, vₚ ⋅ wₚ
|
||||
```
|
||||
|
||||
This only works when the three vectors do not all lie in the same plane. In general, this is the beginning of the [Gram-Schmidt](https://en.wikipedia.org/wiki/Gram-Schmidt_process) process for creating *orthogonal* vectors from a collection of vectors.
|
||||
@ -839,11 +839,8 @@ The volume of a parallelepiped is the area of a base parallelogram times the hei
|
||||
that is, the area of the parallelepiped. Wait, what about $(\vec{v}\times\vec{u})\cdot\vec{w}$? That will have an opposite sign. Yes, in the above, there is an assumption that $\vec{n}$ and $\vec{w}$ have a an angle between them within $[0, \pi/2]$, otherwise an absolute value must be used, as volume is non-negative.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
The triple-scalar product, $\vec{u}\cdot(\vec{v}\times\vec{w})$, gives the volume of the parallelepiped up to sign. If the sign of this is positive, the ``3`` vectors are said to have a *positive* orientation, if the triple-scalar product is negative, the vectors have a *negative* orientation.
|
||||
""", title="Orientation")
|
||||
```
|
||||
!!! note "Orientation"
|
||||
The triple-scalar product, $\vec{u}\cdot(\vec{v}\times\vec{w})$, gives the volume of the parallelepiped up to sign. If the sign of this is positive, the ``3`` vectors are said to have a *positive* orientation, if the triple-scalar product is negative, the vectors have a *negative* orientation.
|
||||
|
||||
|
||||
#### Algebraic properties
|
||||
@ -1046,8 +1043,8 @@ Are `v` and `w` orthogonal?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
u,v,w = [1,2,3], [4,3,2], [5,2,1]
|
||||
ans = dot(v,w) == 0
|
||||
yesnoq(ans)
|
||||
answ = dot(v,w) == 0
|
||||
yesnoq(answ)
|
||||
```
|
||||
|
||||
Find the angle between `u` and `w`:
|
||||
@ -1068,8 +1065,8 @@ choices = [
|
||||
"`[-1, 6, -7]`",
|
||||
"`[-4, 14, -8]`"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Find the area of the parallelogram formed by `v` and `w`
|
||||
@ -1114,8 +1111,8 @@ choices = [
|
||||
"An object of type `Base.Iterators.Zip` that is only realized when used",
|
||||
"A vector of values `[(1, 5), (2, 4), (3, 2)]`"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
What does `prod.(zip(u,v))` return?
|
||||
@ -1125,8 +1122,8 @@ choices = [
|
||||
"A vector of values `[5, 8, 6]`",
|
||||
"An object of type `Base.Iterators.Zip` that when realized will produce a vector of values"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1143,8 +1140,8 @@ choices = [
|
||||
"``0``",
|
||||
"Can't say in general"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1167,8 +1164,8 @@ choices = [
|
||||
"``x + 2y + z = 0``",
|
||||
"``x + 2y + 3z = 6``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1181,8 +1178,8 @@ choices = [
|
||||
" ``\\vec{v}`` is in plane ``P_1``, as it is orthogonal to ``\\vec{n}_1`` and ``P_2`` as it is orthogonal to ``\\vec{n}_2``, hence it is parallel to both planes.",
|
||||
" ``\\vec{n}_1`` and ``\\vec{n_2}`` are unit vectors, so the cross product gives the projection, which must be orthogonal to each vector, hence in the intersection"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1195,8 +1192,8 @@ choices = [
|
||||
"``\\langle 12, 12 \\rangle``",
|
||||
"``12 \\langle 1, 0 \\rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
If the vector to 3 o'clock is removed, (call this $\langle 1, 0 \rangle$) what expresses the sum of *all* the remaining vectors?
|
||||
@ -1207,8 +1204,8 @@ choices = [
|
||||
"``\\langle 1, 0 \\rangle``",
|
||||
"``\\langle 11, 11 \\rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1221,8 +1218,8 @@ choices = [
|
||||
"``\\vec{u} + \\vec{v}``",
|
||||
"``\\vec{u}\\cdot\\vec{v} + \\vec{v}\\cdot \\vec{v}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
As the two are equal, which interpretation is true?
|
||||
@ -1233,8 +1230,8 @@ choices = [
|
||||
"The vector ``\\vec{w}`` must also be a unit vector",
|
||||
"the two are orthogonal"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1251,8 +1248,8 @@ choices = [
|
||||
"``\\vec{u}\\cdot\\vec{v} = 2``",
|
||||
"``\\vec{u}\\cdot\\vec{v} = -(\\vec{u}\\cdot\\vec{u} \\vec{v}\\cdot\\vec{v})``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1274,8 +1271,8 @@ choices = [
|
||||
"The vectors are *orthogonal*, so these are all zero",
|
||||
"The vectors are all unit lengths, so these are all 1"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1311,8 +1308,8 @@ choices = [
|
||||
"``n_1 (\\hat{v_1}\\times\\hat{N}) = n_2 (\\hat{v_2}\\times\\hat{N})``",
|
||||
"``n_1 (\\hat{v_1}\\times\\hat{N}) = -n_2 (\\hat{v_2}\\times\\hat{N})``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1334,6 +1331,6 @@ choices = [
|
||||
"``\\vec{a}``",
|
||||
"``\\vec{a} + \\vec{b} + \\vec{c}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -62,10 +62,10 @@ nothing
|
||||
|
||||
The gradient of a scalar function $f:R^n \rightarrow R$ is a vector field of partial derivatives. In $R^2$, we have:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla{f} = \langle \frac{\partial{f}}{\partial{x}},
|
||||
\frac{\partial{f}}{\partial{y}} \rangle.
|
||||
~$$
|
||||
```
|
||||
|
||||
It has the interpretation of pointing out the direction of greatest ascent for the surface $z=f(x,y)$.
|
||||
|
||||
@ -113,15 +113,15 @@ p
|
||||
|
||||
Consider the sides with outward normal $\hat{i}$. The contribution to the surface integral, $\oint_S (F\cdot\hat{N})dS$, could be *approximated* by
|
||||
|
||||
$$~
|
||||
```math
|
||||
\left(F(x + \Delta x, y, z) \cdot \hat{i}\right) \Delta y \Delta z,
|
||||
~$$
|
||||
```
|
||||
|
||||
whereas, the contribution for the face with outward normal $-\hat{i}$ could be approximated by:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\left(F(x, y, z) \cdot (-\hat{i}) \right) \Delta y \Delta z.
|
||||
~$$
|
||||
```
|
||||
|
||||
The functions are being evaluated at a point on the face of the
|
||||
surface. For Riemann integrable functions, any point in a partition
|
||||
@ -129,11 +129,11 @@ may be chosen, so our choice will not restrict the generality.
|
||||
|
||||
The total contribution of the two would be:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\left(F(x + \Delta x, y, z) \cdot \hat{i}\right) \Delta y \Delta z +
|
||||
\left(F(x, y, z) \cdot (-\hat{i})\right) \Delta y \Delta z =
|
||||
\left(F_x(x + \Delta x, y, z) - F_x(x, y, z)\right) \Delta y \Delta z,
|
||||
~$$
|
||||
```
|
||||
|
||||
as $F \cdot \hat{i} = F_x$.
|
||||
|
||||
@ -142,11 +142,11 @@ as $F \cdot \hat{i} = F_x$.
|
||||
If this is repeated for the other two pair of matching faces, we get a definition for the *divergence*:
|
||||
|
||||
> The *divergence* of a vector field $F:R^3 \rightarrow R^3$ is given by
|
||||
> $$~
|
||||
> ```math
|
||||
> \text{divergence}(F) =
|
||||
> \lim \frac{1}{\Delta V} \oint_S F\cdot\hat{N} dS =
|
||||
> \frac{\partial{F_x}}{\partial{x}} +\frac{\partial{F_y}}{\partial{y}} +\frac{\partial{F_z}}{\partial{z}}.
|
||||
> ~$$
|
||||
> ```
|
||||
|
||||
The limit expression for the divergence will hold for any smooth closed surface, $S$, converging on $(x,y,z)$, not just box-like ones.
|
||||
|
||||
@ -155,9 +155,9 @@ The limit expression for the divergence will hold for any smooth closed surface,
|
||||
|
||||
The derivation of the divergence is done for $n=3$, but could also have easily been done for two dimensions ($n=2$) or higher dimensions $n>3$. The formula in general would be: for $F(x_1, x_2, \dots, x_n): R^n \rightarrow R^n$:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\text{divergence}(F) = \sum_{i=1}^n \frac{\partial{F_i}}{\partial{x_i}}.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
----
|
||||
@ -198,7 +198,7 @@ annotate!([
|
||||
|
||||
Let $F=\langle F_x, F_y\rangle$. For small enough values of $\Delta{x}$ and $\Delta{y}$ the line integral, $\oint_C F\cdot d\vec{r}$ can be *approximated* by $4$ terms:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\left(F(x,y) \cdot \hat{i}\right)\Delta{x} &+
|
||||
\left(F(x+\Delta{x},y) \cdot \hat{j}\right)\Delta{y} +
|
||||
@ -211,15 +211,15 @@ F_x(x, y+\Delta{y}) (-\Delta{x}) + F_y(x,y) (-\Delta{y})\\
|
||||
(F_y(x + \Delta{x}, y) - F_y(x, y))\Delta{y} -
|
||||
(F_x(x, y+\Delta{y})-F_x(x,y))\Delta{x}.
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
The Riemann approximation allows a choice of evaluation point for Riemann integrable functions, and the choice here lends itself to further analysis.
|
||||
Were the above divided by $\Delta{x}\Delta{y}$, the area of the box, and a limit taken, partial derivatives appear to suggest this formula:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\lim \frac{1}{\Delta{x}\Delta{y}} \oint_C F\cdot d\vec{r} =
|
||||
\frac{\partial{F_y}}{\partial{x}} - \frac{\partial{F_x}}{\partial{y}}.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
The scalar function on the right hand side is called the (two-dimensional) curl of $F$ and the left-hand side lends itself as a measure of the microscopic circulation of the vector field, $F:R^2 \rightarrow R^2$.
|
||||
@ -303,31 +303,36 @@ p
|
||||
|
||||
Now we compute the *line integral*. Consider the top face, $S_1$, connecting $(x,y,z+\Delta z), (x + \Delta x, y, z + \Delta z), (x + \Delta x, y + \Delta y, z + \Delta z), (x, y + \Delta y, z + \Delta z)$, Using the *right hand rule*, parameterize the boundary curve, $C_1$, in a counter clockwise direction so the right hand rule yields the outward pointing normal ($\hat{k}$). Then the integral $\oint_{C_1} F\cdot \hat{T} ds$ is *approximated* by the following Riemann sum of $4$ terms:
|
||||
|
||||
$$~
|
||||
F(x,y, z+\Delta{z}) \cdot \hat{i}\Delta{x} +
|
||||
F(x+\Delta x, y, z+\Delta{z}) \cdot \hat{j} \Delta y +
|
||||
F(x, y+\Delta y, z+\Delta{z}) \cdot (-\hat{i}) \Delta{x} +
|
||||
F(x, y, z+\Delta{z}) \cdot (-\hat{j}) \Delta{y}.
|
||||
~$$
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
F(x,y, z+\Delta{z}) \cdot \hat{i}\Delta{x} &+ F(x+\Delta x, y, z+\Delta{z}) \cdot \hat{j} \Delta y \\
|
||||
&+ F(x, y+\Delta y, z+\Delta{z}) \cdot (-\hat{i}) \Delta{x} \\
|
||||
&+ F(x, y, z+\Delta{z}) \cdot (-\hat{j}) \Delta{y}.
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
(The points $c_i$ are chosen from the endpoints of the line segments.)
|
||||
|
||||
|
||||
|
||||
$$~
|
||||
\oint_{C_1} F\cdot \hat{T} ds \approx
|
||||
(F_y(x+\Delta x, y, z+\Delta{z}) - F_y(x, y, z+\Delta{z})) \Delta{y} -
|
||||
(F_x(x,y + \Delta{y}, z+\Delta{z}) - F_x(x, y, z+\Delta{z})) \Delta{x}
|
||||
~$$
|
||||
```math
|
||||
\begin{align*}
|
||||
\oint_{C_1} F\cdot \hat{T} ds
|
||||
&\approx (F_y(x+\Delta x, y, z+\Delta{z}) \\
|
||||
&- F_y(x, y, z+\Delta{z})) \Delta{y} \\
|
||||
&- (F_x(x,y + \Delta{y}, z+\Delta{z}) \\
|
||||
&- F_x(x, y, z+\Delta{z})) \Delta{x}
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
As before, were this divided by the *area* of the surface, we have after rearranging and cancellation:
|
||||
|
||||
$$~
|
||||
\frac{1}{\Delta{S_1}} \oint_{C_1} F \cdot \hat{T} ds \approx
|
||||
\frac{F_y(x+\Delta x, y, z+\Delta{z}) - F_y(x, y, z+\Delta{z})}{\Delta{x}}
|
||||
-
|
||||
\frac{F_x(x, y+\Delta y, z+\Delta{z})-F_x(x, y, z+\Delta{z})}{\Delta{y}}.
|
||||
~$$
|
||||
```math
|
||||
\begin{align*}
|
||||
\frac{1}{\Delta{S_1}} \oint_{C_1} F \cdot \hat{T} ds &\approx
|
||||
\frac{F_y(x+\Delta x, y, z+\Delta{z}) - F_y(x, y, z+\Delta{z})}{\Delta{x}}\\
|
||||
&- \frac{F_x(x, y+\Delta y, z+\Delta{z}) - F_x(x, y, z+\Delta{z})}{\Delta{y}}.
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
In the limit, as $\Delta{S} \rightarrow 0$, this will converge to $\partial{F_y}/\partial{x}-\partial{F_x}/\partial{y}$.
|
||||
|
||||
@ -336,56 +341,56 @@ Had the bottom of the box been used, a similar result would be found, up to a mi
|
||||
Unlike the two dimensional case, there are other directions to consider and here
|
||||
the other sides will yield different answers. Consider now the face connecting $(x,y,z), (x+\Delta{x}, y, z), (x+\Delta{x}, y, z + \Delta{z})$, and $ (x,y,z+\Delta{z})$ with outward pointing normal $-\hat{j}$. Let $S_2$ denote this face and $C_2$ describe its boundary. Orient this curve so that the right hand rule points in the $-\hat{j}$ direction (the outward pointing normal). Then, as before, we can approximate:
|
||||
|
||||
$$~
|
||||
\begin{align}
|
||||
```math
|
||||
\begin{align*}
|
||||
\oint_{C_2} F \cdot \hat{T} ds
|
||||
&\approx
|
||||
F(x,y,z) \cdot \hat{i} \Delta{x} +
|
||||
F(x+\Delta{x},y,z) \cdot \hat{k} \Delta{z} +
|
||||
F(x,y,z+\Delta{z}) \cdot (-\hat{i}) \Delta{x} +
|
||||
F(x, y, z) \cdot (-\hat{k}) \Delta{z}\\
|
||||
F(x,y,z) \cdot \hat{i} \Delta{x} \\
|
||||
&+ F(x+\Delta{x},y,z) \cdot \hat{k} \Delta{z} \\
|
||||
&+ F(x,y,z+\Delta{z}) \cdot (-\hat{i}) \Delta{x} \\
|
||||
&+ F(x, y, z) \cdot (-\hat{k}) \Delta{z}\\
|
||||
&= (F_z(x+\Delta{x},y,z) - F_z(x, y, z))\Delta{z} -
|
||||
(F_x(x,y,z+\Delta{z}) - F(x,y,z)) \Delta{x}.
|
||||
\end{align}
|
||||
~$$
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
Dividing by $\Delta{S}=\Delta{x}\Delta{z}$ and taking a limit will give:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\lim \frac{1}{\Delta{S}} \oint_{C_2} F \cdot \hat{T} ds =
|
||||
\frac{\partial{F_z}}{\partial{x}} - \frac{\partial{F_x}}{\partial{z}}.
|
||||
~$$
|
||||
```
|
||||
|
||||
Had, the opposite face with outward normal $\hat{j}$ been chosen, the answer would differ by a factor of $-1$.
|
||||
|
||||
Similarly, let $S_3$ be the face with outward normal $\hat{i}$ and curve $C_3$ bounding it with parameterization chosen so that the right hand rule points in the direction of $\hat{i}$. This will give
|
||||
|
||||
|
||||
$$~
|
||||
```math
|
||||
\lim \frac{1}{\Delta{S}} \oint_{C_3} F \cdot \hat{T} ds =
|
||||
\frac{\partial{F_z}}{\partial{y}} - \frac{\partial{F_y}}{\partial{z}}.
|
||||
~$$
|
||||
```
|
||||
|
||||
In short, depending on the face chosen, a different answer is given, but all have the same type.
|
||||
|
||||
> Define the *curl* of a $3$-dimensional vector field $F=\langle F_x,F_y,F_z\rangle$ by:
|
||||
> $$~
|
||||
> ```math
|
||||
> \text{curl}(F) =
|
||||
> \langle \frac{\partial{F_z}}{\partial{y}} - \frac{\partial{F_y}}{\partial{z}},
|
||||
> \frac{\partial{F_x}}{\partial{z}} - \frac{\partial{F_z}}{\partial{x}},
|
||||
> \frac{\partial{F_y}}{\partial{x}} - \frac{\partial{F_x}}{\partial{y}} \rangle.
|
||||
> ~$$
|
||||
> ```
|
||||
|
||||
If $S$ is some surface with closed boundary $C$ oriented so that the unit normal, $\hat{N}$, of $S$ is given by the right hand rule about $C$, then
|
||||
|
||||
$$~
|
||||
```math
|
||||
\hat{N} \cdot \text{curl}(F) = \lim \frac{1}{\Delta{S}} \oint_C F \cdot \hat{T} ds.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
The curl has a formal representation in terms of a $3\times 3$ determinant, similar to that used to compute the cross product, that is useful for computation:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\text{curl}(F) = \det\left[
|
||||
\begin{array}{}
|
||||
\hat{i} & \hat{j} & \hat{k}\\
|
||||
@ -393,7 +398,7 @@ $$~
|
||||
F_x & F_y & F_z
|
||||
\end{array}
|
||||
\right]
|
||||
~$$
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
@ -419,18 +424,18 @@ curl(F::Function, pt) = curl(ForwardDiff.jacobian(F, pt))
|
||||
|
||||
The divergence, gradient, and curl all involve partial derivatives. There is a notation employed that can express the operations more succinctly. Let the [Del operator](https://en.wikipedia.org/wiki/Del) be defined in Cartesian coordinates by the formal expression:
|
||||
|
||||
> $$~
|
||||
> ```math
|
||||
> \nabla = \langle
|
||||
> \frac{\partial}{\partial{x}},
|
||||
> \frac{\partial}{\partial{y}},
|
||||
> \frac{\partial}{\partial{z}}
|
||||
> \rangle.
|
||||
> ~$$
|
||||
> ```
|
||||
|
||||
This is a *vector differential operator* that acts on functions and vector fields through the typical notation to yield the three operations:
|
||||
|
||||
$$~
|
||||
\begin{align}
|
||||
```math
|
||||
\begin{align*}
|
||||
\nabla{f} &= \langle
|
||||
\frac{\partial{f}}{\partial{x}},
|
||||
\frac{\partial{f}}{\partial{y}},
|
||||
@ -440,13 +445,15 @@ $$~
|
||||
\frac{\partial}{\partial{x}},
|
||||
\frac{\partial}{\partial{y}},
|
||||
\frac{\partial}{\partial{z}}
|
||||
\rangle \cdot F =
|
||||
\rangle \cdot F \\
|
||||
&=
|
||||
\langle
|
||||
\frac{\partial}{\partial{x}},
|
||||
\frac{\partial}{\partial{y}},
|
||||
\frac{\partial}{\partial{z}}
|
||||
\rangle \cdot
|
||||
\langle F_x, F_y, F_z \rangle =
|
||||
\langle F_x, F_y, F_z \rangle \\
|
||||
&=
|
||||
\frac{\partial{F_x}}{\partial{x}} +
|
||||
\frac{\partial{F_y}}{\partial{y}} +
|
||||
\frac{\partial{F_z}}{\partial{z}},\quad\text{the divergence;}\\
|
||||
@ -464,15 +471,12 @@ $$~
|
||||
F_x & F_y & F_z
|
||||
\end{array}
|
||||
\right],\quad\text{the curl}.
|
||||
\end{align}
|
||||
~$$
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
Mathematically operators have not been seen previously, but the concept of an operation on a function that returns another function is a common one when using `Julia`. We have seen many examples (`plot`, `D`, `quadgk`, etc.). In computer science such functions are called *higher order* functions, as they accept arguments which are also functions.
|
||||
""")
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
!!! note
|
||||
Mathematically operators have not been seen previously, but the concept of an operation on a function that returns another function is a common one when using `Julia`. We have seen many examples (`plot`, `D`, `quadgk`, etc.). In computer science such functions are called *higher order* functions, as they accept arguments which are also functions.
|
||||
|
||||
----
|
||||
|
||||
In the `CalculusWithJulia` package, the constant `\nabla[\tab]`, producing $\nabla$ implements this operator for functions and symbolic expressions.
|
||||
@ -543,11 +547,9 @@ There is a subtle difference in usage. Symbolically the evaluation of
|
||||
function evaluation, parentheses must be used in the numeric case.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
As mentioned, for the symbolic evaluations, a specification of three variables (here `x`, `y`, and `z`) is necessary. This use takes `free_symbols` to identify three free symbols which may not always be the case. (It wouldn't be for, say, `F(x,y,z) = [a*x,b*y,0]`, `a` and `b` constants.) In those cases, the notation accepts a tuple to specify the function or vector field and the variables, e.g. (`∇( (f(x,y,z), [x,y,z]) )`, as illustrated; `∇ × (F(x,y,z), [x,y,z])`; or `∇ ⋅ (F(x,y,z), [x,y,z])` where this is written using function calls to produce the symbolic expression in the first positional argument, though a direct expression could also be used. In these cases, the named versions `gradient`, `curl`, and `divergence` may be preferred.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
As mentioned, for the symbolic evaluations, a specification of three variables (here `x`, `y`, and `z`) is necessary. This use takes `free_symbols` to identify three free symbols which may not always be the case. (It wouldn't be for, say, `F(x,y,z) = [a*x,b*y,0]`, `a` and `b` constants.) In those cases, the notation accepts a tuple to specify the function or vector field and the variables, e.g. (`∇( (f(x,y,z), [x,y,z]) )`, as illustrated; `∇ × (F(x,y,z), [x,y,z])`; or `∇ ⋅ (F(x,y,z), [x,y,z])` where this is written using function calls to produce the symbolic expression in the first positional argument, though a direct expression could also be used. In these cases, the named versions `gradient`, `curl`, and `divergence` may be preferred.
|
||||
|
||||
|
||||
|
||||
|
||||
@ -588,9 +590,9 @@ p
|
||||
|
||||
Consider the limit definition of the divergence:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla\cdot{F} = \lim \frac{1}{\Delta{V}} \oint_S F\cdot\hat{N} dA.
|
||||
~$$
|
||||
```
|
||||
|
||||
In the vector field above, the shape along the curved edges has constant magnitude field. On the left curved edge, the length is smaller and the field is smaller than on the right. The flux across the left edge will be less than the flux across the right edge, and a net flux will exist. That is, there is divergence.
|
||||
|
||||
@ -747,37 +749,37 @@ Let $f$ and $g$ denote scalar functions, $R^3 \rightarrow R$ and $F$ and $G$ be
|
||||
|
||||
As with the sum rule of univariate derivatives, these operations satisfy:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\nabla(f + g) &= \nabla{f} + \nabla{g}\\
|
||||
\nabla\cdot(F+G) &= \nabla\cdot{F} + \nabla\cdot{G}\\
|
||||
\nabla\times(F+G) &= \nabla\times{F} + \nabla\times{G}.
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
### Product rule
|
||||
|
||||
The product rule $(uv)' = u'v + uv'$ has related formulas:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\nabla{(fg)} &= (\nabla{f}) g + f\nabla{g} = g\nabla{f} + f\nabla{g}\\
|
||||
\nabla\cdot{fF} &= (\nabla{f})\cdot{F} + f(\nabla\cdot{F})\\
|
||||
\nabla\times{fF} &= (\nabla{f})\times{F} + f(\nabla\times{F}).
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
### Rules over cross products
|
||||
|
||||
The cross product of two vector fields is a vector field for which the divergence and curl may be taken. There are formulas to relate to the individual terms:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\nabla\cdot(F \times G) &= (\nabla\times{F})\cdot G - F \cdot (\nabla\times{G})\\
|
||||
\nabla\times(F \times G) &= F(\nabla\cdot{G}) - G(\nabla\cdot{F} + (G\cdot\nabla)F-(F\cdot\nabla)G\\
|
||||
&= \nabla\cdot(BA^t - AB^t).
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
The curl formula is more involved.
|
||||
|
||||
### Vanishing properties
|
||||
@ -785,9 +787,9 @@ The curl formula is more involved.
|
||||
Surprisingly, the curl and divergence satisfy two vanishing properties. First
|
||||
|
||||
> The curl of a gradient field is $\vec{0}$
|
||||
> $$~
|
||||
> ```math
|
||||
> \nabla \times \nabla{f} = \vec{0},
|
||||
> ~$$
|
||||
> ```
|
||||
|
||||
if the scalar function $f$ is has continuous second derivatives (so the mixed partials do not depend on order).
|
||||
|
||||
@ -800,14 +802,15 @@ The combination $\nabla\cdot\nabla{f}$ is defined and is called the Laplacian. T
|
||||
Second,
|
||||
|
||||
> The divergence of a curl field is $0$:
|
||||
>$$~
|
||||
>```math
|
||||
>\nabla \cdot(\nabla\times{F}) = 0.
|
||||
> ~$$
|
||||
> ```
|
||||
|
||||
This is not as clear, but can be seen algebraically as terms cancel. First:
|
||||
|
||||
$$~
|
||||
\nabla\cdot(\nabla\times{F}) =
|
||||
```math
|
||||
\begin{align*}
|
||||
\nabla\cdot(\nabla\times{F}) &=
|
||||
\langle
|
||||
\frac{\partial}{\partial{x}},
|
||||
\frac{\partial}{\partial{y}},
|
||||
@ -816,19 +819,20 @@ $$~
|
||||
\frac{\partial{F_z}}{\partial{y}} - \frac{\partial{F_y}}{\partial{z}},
|
||||
\frac{\partial{F_x}}{\partial{z}} - \frac{\partial{F_z}}{\partial{x}},
|
||||
\frac{\partial{F_y}}{\partial{x}} - \frac{\partial{F_x}}{\partial{y}}
|
||||
\rangle
|
||||
=
|
||||
\rangle \\
|
||||
&=
|
||||
\left(\frac{\partial^2{F_z}}{\partial{y}\partial{x}} - \frac{\partial^2{F_y}}{\partial{z}\partial{x}}\right) +
|
||||
\left(\frac{\partial^2{F_x}}{\partial{z}\partial{y}} - \frac{\partial^2{F_z}}{\partial{x}\partial{y}}\right) +
|
||||
\left(\frac{\partial^2{F_y}}{\partial{x}\partial{z}} - \frac{\partial^2{F_x}}{\partial{y}\partial{z}}\right)
|
||||
~$$
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
Focusing on one component function, $F_z$ say, we see this contribution:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\frac{\partial^2{F_z}}{\partial{y}\partial{x}} -
|
||||
\frac{\partial^2{F_z}}{\partial{x}\partial{y}}.
|
||||
~$$
|
||||
```
|
||||
|
||||
This is zero under the assumption that the second partial derivatives are continuous.
|
||||
|
||||
@ -887,12 +891,17 @@ This is because of how the line integrals are oriented so that the right-hand ru
|
||||
|
||||
The [invariance of charge](https://en.wikipedia.org/wiki/Maxwell%27s_equations#Charge_conservation) can be derived as a corollary of Maxwell's equation. The divergence of the curl of the magnetic field is $0$, leading to:
|
||||
|
||||
$$~
|
||||
0 = \nabla\cdot(\nabla\times{B}) =
|
||||
\mu_0(\nabla\cdot{J} + \epsilon_0 \nabla\cdot{\frac{\partial{E}}{\partial{t}}}) =
|
||||
\mu_0(\nabla\cdot{J} + \epsilon_0 \frac{\partial}{\partial{t}}(\nabla\cdot{E}))
|
||||
= \mu_0(\nabla\cdot{J} + \frac{\partial{\rho}}{\partial{t}}).
|
||||
~$$
|
||||
```mat
|
||||
\begin{align*}
|
||||
0 &= \nabla\cdot(\nabla\times{B}) \\
|
||||
&=
|
||||
\mu_0(\nabla\cdot{J} + \epsilon_0 \nabla\cdot{\frac{\partial{E}}{\partial{t}}}) \\
|
||||
&=
|
||||
\mu_0(\nabla\cdot{J} + \epsilon_0 \frac{\partial}{\partial{t}}(\nabla\cdot{E})) \\
|
||||
&=
|
||||
\mu_0(\nabla\cdot{J} + \frac{\partial{\rho}}{\partial{t}}).
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
That is $\nabla\cdot{J} = -\partial{\rho}/\partial{t}$.
|
||||
This says any change in the charge density in time ($\partial{\rho}/\partial{t}$) is balanced off by a divergence in the electric current density ($\nabla\cdot{J}$). That is, charge can't be created or destroyed in an isolated system.
|
||||
@ -907,14 +916,14 @@ From [Wikipedia](https://en.wikipedia.org/wiki/Helmholtz_decomposition) we have
|
||||
|
||||
Let $F$ be a vector field on a **bounded** domain $V$ which is twice continuously differentiable. Let $S$ be the surface enclosing $V$. Then $F$ can be decomposed into a curl-free component and a divergence-free component:
|
||||
|
||||
$$~
|
||||
```math
|
||||
F = -\nabla(\phi) + \nabla\times A.
|
||||
~$$
|
||||
```
|
||||
|
||||
Without explaining why, these values can be computed using volume and
|
||||
surface integrals:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\phi(\vec{r}') &=
|
||||
\frac{1}{4\pi} \int_V \frac{\nabla \cdot F(\vec{r})}{\|\vec{r}'-\vec{r} \|} dV -
|
||||
@ -922,16 +931,16 @@ $$~
|
||||
A(\vec{r}') &= \frac{1}{4\pi} \int_V \frac{\nabla \times F(\vec{r})}{\|\vec{r}'-\vec{r} \|} dV +
|
||||
\frac{1}{4\pi} \oint_S \frac{F(\vec{r})}{\|\vec{r}'-\vec{r} \|} \times \hat{N} dS.
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
If $V = R^3$, an unbounded domain, *but* $F$ *vanishes* faster than $1/r$, then the theorem still holds with just the volume integrals:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\phi(\vec{r}') &=\frac{1}{4\pi} \int_V \frac{\nabla \cdot F(\vec{r})}{\|\vec{r}'-\vec{r} \|} dV\\
|
||||
A(\vec{r}') &= \frac{1}{4\pi} \int_V \frac{\nabla \times F(\vec{r})}{\|\vec{r}'-\vec{r}\|} dV.
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
## Change of variable
|
||||
@ -942,7 +951,7 @@ Some details are [here](https://en.wikipedia.org/wiki/Curvilinear_coordinates),
|
||||
|
||||
We restrict to $n=3$ and use $(x,y,z)$ for Cartesian coordinates and $(u,v,w)$ for an *orthogonal* curvilinear coordinate system, such as spherical or cylindrical. If $\vec{r} = \langle x,y,z\rangle$, then
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
d\vec{r} &= \langle dx,dy,dz \rangle = J \langle du,dv,dw\rangle\\
|
||||
&=
|
||||
@ -953,55 +962,58 @@ d\vec{r} &= \langle dx,dy,dz \rangle = J \langle du,dv,dw\rangle\\
|
||||
\frac{\partial{\vec{r}}}{\partial{v}} dv
|
||||
\frac{\partial{\vec{r}}}{\partial{w}} dw.
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
The term ${\partial{\vec{r}}}/{\partial{u}}$ is tangent to the curve formed by *assuming* $v$ and $w$ are constant and letting $u$ vary. Similarly for the other partial derivatives. Orthogonality assumes that at every point, these tangent vectors are orthogonal.
|
||||
|
||||
As ${\partial{\vec{r}}}/{\partial{u}}$ is a vector it has a magnitude and direction. Define the scale factors as the magnitudes:
|
||||
|
||||
$$~
|
||||
```math
|
||||
h_u = \| \frac{\partial{\vec{r}}}{\partial{u}} \|,\quad
|
||||
h_v = \| \frac{\partial{\vec{r}}}{\partial{v}} \|,\quad
|
||||
h_w = \| \frac{\partial{\vec{r}}}{\partial{w}} \|.
|
||||
~$$
|
||||
```
|
||||
|
||||
and let $\hat{e}_u$, $\hat{e}_v$, and $\hat{e}_w$ be the unit, direction vectors.
|
||||
|
||||
This gives the following notation:
|
||||
|
||||
$$~
|
||||
```math
|
||||
d\vec{r} = h_u du \hat{e}_u + h_v dv \hat{e}_v + h_w dw \hat{e}_w.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
From here, we can express different formulas.
|
||||
|
||||
For line integrals, we have the line element:
|
||||
|
||||
$$~
|
||||
```math
|
||||
dl = \sqrt{d\vec{r}\cdot d\vec{r}} = \sqrt{(h_ud_u)^2 + (h_vd_v)^2 + (h_wd_w)^2}.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
Consider the surface for constant $u$. The vector $\hat{e}_v$ and $\hat{e}_w$ lie in the surface's tangent plane, and the surface element will be:
|
||||
|
||||
$$~
|
||||
```math
|
||||
dS_u = \| h_v dv \hat{e}_v \times h_w dw \hat{e}_w \| = h_v h_w dv dw \| \hat{e}_v \| = h_v h_w dv dw.
|
||||
~$$
|
||||
```
|
||||
|
||||
This uses orthogonality, so $\hat{e}_v \times \hat{e}_w$ is parallel to $\hat{e}_u$ and has unit length. Similarly, $dS_v = h_u h_w du dw$ and $dS_w = h_u h_v du dv$ .
|
||||
|
||||
The volume element is found by *projecting* $d\vec{r}$ onto the $\hat{e}_u$, $\hat{e}_v$, $\hat{e}_w$ coordinate system through $(d\vec{r} \cdot\hat{e}_u) \hat{e}_u$, $(d\vec{r} \cdot\hat{e}_v) \hat{e}_v$, and $(d\vec{r} \cdot\hat{e}_w) \hat{e}_w$. Then forming the triple scalar product to compute the volume of the parallelepiped:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align*}
|
||||
\left[(d\vec{r} \cdot\hat{e}_u) \hat{e}_u\right] \cdot
|
||||
\left(
|
||||
\left[(d\vec{r} \cdot\hat{e}_v) \hat{e}_v\right] \times
|
||||
\left[(d\vec{r} \cdot\hat{e}_w) \hat{e}_w\right]
|
||||
\right) =
|
||||
(h_u h_v h_w) ( du dv dw ) (\hat{e}_u \cdot (\hat{e}_v \times \hat{e}_w) =
|
||||
\right) &=
|
||||
(h_u h_v h_w) ( du dv dw ) (\hat{e}_u \cdot (\hat{e}_v \times \hat{e}_w) \\
|
||||
&=
|
||||
h_u h_v h_w du dv dw,
|
||||
~$$
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
as the unit vectors are orthonormal, their triple scalar product is $1$ and $d\vec{r}\cdot\hat{e}_u = h_u du$, etc.
|
||||
|
||||
@ -1010,13 +1022,13 @@ as the unit vectors are orthonormal, their triple scalar product is $1$ and $d\v
|
||||
|
||||
We consider spherical coordinates with
|
||||
|
||||
$$~
|
||||
```math
|
||||
F(r, \theta, \phi) = \langle
|
||||
r \sin(\phi) \cos(\theta),
|
||||
r \sin(\phi) \sin(\theta),
|
||||
r \cos(\phi)
|
||||
\rangle.
|
||||
~$$
|
||||
```
|
||||
|
||||
The following figure draws curves starting at $(r_0, \theta_0, \phi_0)$ formed by holding $2$ of the $3$ variables constant. The tangent vectors are added in blue. The surface $S_r$ formed by a constant value of $r$ is illustrated.
|
||||
|
||||
@ -1061,7 +1073,7 @@ p
|
||||
|
||||
The tangent vectors found from the partial derivatives of $\vec{r}$:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\frac{\partial{\vec{r}}}{\partial{r}} &=
|
||||
\langle \cos(\theta) \cdot \sin(\phi), \sin(\theta) \cdot \sin(\phi), \cos(\phi)\rangle,\\
|
||||
@ -1070,17 +1082,19 @@ $$~
|
||||
\frac{\partial{\vec{r}}}{\partial{\phi}} &=
|
||||
\langle r\cdot\cos(\theta)\cdot\cos(\phi), r\cdot\sin(\theta)\cdot\cos(\phi), -r\cdot\sin(\phi) \rangle.
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
With this, we have $h_r=1$, $h_\theta=r\sin(\phi)$, and $h_\phi = r$. So that
|
||||
|
||||
$$~
|
||||
dl = \sqrt{dr^2 + (r\sin(\phi)d\theta^2) + (rd\phi)^2},\quad
|
||||
dS_r = r^2\sin(\phi)d\theta d\phi,\quad
|
||||
dS_\theta = rdr d\phi,\quad
|
||||
dS_\phi = r\sin(\phi)dr d\theta, \quad\text{and}\quad
|
||||
dV = r^2\sin(\phi) drd\theta d\phi.
|
||||
~$$
|
||||
```math
|
||||
\begin{align*}
|
||||
dl &= \sqrt{dr^2 + (r\sin(\phi)d\theta^2) + (rd\phi)^2},\\
|
||||
dS_r &= r^2\sin(\phi)d\theta d\phi,\\
|
||||
dS_\theta &= rdr d\phi,\\
|
||||
dS_\phi &= r\sin(\phi)dr d\theta, \quad\text{and}\\
|
||||
dV &= r^2\sin(\phi) drd\theta d\phi.
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
The following visualizes the volume and the surface elements.
|
||||
|
||||
@ -1132,25 +1146,27 @@ p
|
||||
|
||||
If $f$ is a scalar function then $df = \nabla{f} \cdot d\vec{r}$ by the chain rule. Using the curvilinear coordinates:
|
||||
|
||||
$$~
|
||||
df =
|
||||
```math
|
||||
\begin{align*}
|
||||
df &=
|
||||
\frac{\partial{f}}{\partial{u}} du +
|
||||
\frac{\partial{f}}{\partial{v}} dv +
|
||||
\frac{\partial{f}}{\partial{w}} dw
|
||||
=
|
||||
\frac{\partial{f}}{\partial{w}} dw \\
|
||||
&=
|
||||
\frac{1}{h_u}\frac{\partial{f}}{\partial{u}} h_udu +
|
||||
\frac{1}{h_v}\frac{\partial{f}}{\partial{v}} h_vdv +
|
||||
\frac{1}{h_w}\frac{\partial{f}}{\partial{w}} h_wdw.
|
||||
~$$
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
But, as was used above, $d\vec{r} \cdot \hat{e}_u = h_u du$, etc. so $df$ can be re-expressed as:
|
||||
|
||||
$$~
|
||||
```math
|
||||
df = (\frac{1}{h_u}\frac{\partial{f}}{\partial{u}}\hat{e}_u +
|
||||
\frac{1}{h_v}\frac{\partial{f}}{\partial{v}}\hat{e}_v +
|
||||
\frac{1}{h_w}\frac{\partial{f}}{\partial{w}}\hat{e}_w) \cdot d\vec{r} =
|
||||
\nabla{f} \cdot d\vec{r}.
|
||||
~$$
|
||||
```
|
||||
|
||||
The gradient is the part within the parentheses.
|
||||
|
||||
@ -1158,55 +1174,55 @@ The gradient is the part within the parentheses.
|
||||
|
||||
As an example, in cylindrical coordinates, we have $h_r =1$, $h_\theta=r$, and $h_z=1$, giving:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla{f} = \frac{\partial{f}}{\partial{r}}\hat{e}_r +
|
||||
\frac{1}{r}\frac{\partial{f}}{\partial{\theta}}\hat{e}_\theta +
|
||||
\frac{\partial{f}}{\partial{z}}\hat{e}_z
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
### The divergence in a new coordinate system
|
||||
|
||||
The divergence is a result of the limit of a surface integral,
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla \cdot F = \lim \frac{1}{\Delta{V}}\oint_S F \cdot \hat{N} dS.
|
||||
~$$
|
||||
```
|
||||
|
||||
Taking $V$ as a box in the curvilinear coordinates, with side lengths $h_udu$, $h_vdv$, and $h_wdw$
|
||||
the surface integral is computed by projecting $F$ onto each normal area element and multiplying by the area. The task is similar to how the the divergence was derived above, only now the terms are like $\partial{(F_uh_vh_w)}/\partial{u}$ due to the scale factors ($F_u$ is the u component of $F$.) The result is:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla\cdot F = \frac{1}{h_u h_v h_w}\left[
|
||||
\frac{\partial{(F_uh_vh_w)}}{\partial{u}} +
|
||||
\frac{\partial{(h_uF_vh_w)}}{\partial{v}} +
|
||||
\frac{\partial{(h_uh_vF_w)}}{\partial{w}} \right].
|
||||
~$$
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
For example, in cylindrical coordinates, we have
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla \cdot F = \frac{1}{r}
|
||||
\left[
|
||||
\frac{\partial{F_r r}}{\partial{r}} +
|
||||
\frac{\partial{F_\theta}}{\partial{\theta}} +
|
||||
\frac{\partial{F_x}}{\partial{z}}
|
||||
\right].
|
||||
~$$
|
||||
```
|
||||
|
||||
### The curl in a new coordinate system
|
||||
|
||||
The curl, like the divergence, can be expressed as the limit of an integral:
|
||||
|
||||
$$~
|
||||
```math
|
||||
(\nabla \times F) \cdot \hat{N} = \lim \frac{1}{\Delta{S}} \oint_C F \cdot d\vec{r},
|
||||
~$$
|
||||
```
|
||||
|
||||
where $S$ is a surface perpendicular to $\hat{N}$ with boundary $C$. For a small rectangular surface, the derivation is similar to above, only the scale factors are included. This gives, say, for the $\hat{e}_u$ normal, $\frac{\partial{(h_zF_z)}}{\partial{y}} - \frac{\partial{(h_yF_y)}}{\partial{z}}$. The following determinant form combines the terms compactly:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla\times{F} = \det \left[
|
||||
\begin{array}{}
|
||||
h_u\hat{e}_u & h_v\hat{e}_v & h_w\hat{e}_w \\
|
||||
@ -1214,13 +1230,13 @@ h_u\hat{e}_u & h_v\hat{e}_v & h_w\hat{e}_w \\
|
||||
h_uF_u & h_v F_v & h_w F_w
|
||||
\end{array}
|
||||
\right].
|
||||
~$$
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
For example, in cylindrical coordinates, the curl is:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\det\left[
|
||||
\begin{array}{}
|
||||
\hat{r} & r\hat{\theta} & \hat{k} \\
|
||||
@ -1228,11 +1244,11 @@ $$~
|
||||
F_r & rF_\theta & F_z
|
||||
\end{array}
|
||||
\right]
|
||||
~$$
|
||||
```
|
||||
|
||||
Applying this to the function $F(r,\theta, z) = \hat{\theta}$ we get:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\text{curl}(F) = \det\left[
|
||||
\begin{array}{}
|
||||
\hat{r} & r\hat{\theta} & \hat{k} \\
|
||||
@ -1247,7 +1263,7 @@ $$~
|
||||
\end{array}
|
||||
\right] =
|
||||
\hat{k}.
|
||||
~$$
|
||||
```
|
||||
|
||||
As $F$ represents a vector field that rotates about the $z$ axis at a constant rate, the magnitude of the curl should be a constant and it should point in the $\hat{k}$ direction, as we found.
|
||||
|
||||
@ -1290,8 +1306,8 @@ raw" ``x y + x e^{x y} + \cos{\left (x \right )}``",
|
||||
raw" ``x y + x e^{x y}``",
|
||||
raw" ``x e^{x y} + \cos{\left (x \right )}``"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1306,8 +1322,8 @@ raw" ``xz``",
|
||||
raw" ``-yz``",
|
||||
raw" ``ye^{xy}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1320,8 +1336,8 @@ raw" ``0``",
|
||||
raw" ``\vec{0}``",
|
||||
raw" ``6``"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1329,21 +1345,21 @@ radioq(choices, ans)
|
||||
|
||||
In two dimension's the curl of a gradient field simplifies to:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla\times\nabla{f} = \nabla\times
|
||||
\langle\frac{\partial{f}}{\partial{x}},
|
||||
\frac{\partial{f}}{\partial{y}}\rangle =
|
||||
\frac{\partial{\frac{\partial{f}}{\partial{y}}}}{\partial{x}} -
|
||||
\frac{\partial{\frac{\partial{f}}{\partial{x}}}}{\partial{y}}.
|
||||
~$$
|
||||
```
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [
|
||||
L"This is $0$ if the partial derivatives are continuous by Schwarz's (Clairault's) theorem",
|
||||
L"This is $0$ for any $f$, as $\nabla\times\nabla$ is $0$ since the cross product of vector with itself is the $0$ vector."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1365,8 +1381,8 @@ choices=[
|
||||
"The field is irrotational (curl free)",
|
||||
"The field has a non-trivial curl and divergence"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ=1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1388,8 +1404,8 @@ choices=[
|
||||
"The field is irrotational (curl free)",
|
||||
"The field has a non-trivial curl and divergence"
|
||||
]
|
||||
ans=2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ=2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1403,8 +1419,8 @@ choices=[
|
||||
"The field is irrotational (curl free)",
|
||||
"The field has a non-trivial curl and divergence"
|
||||
]
|
||||
ans=3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ=3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1419,8 +1435,8 @@ choices=[
|
||||
"The field is irrotational (curl free)",
|
||||
"The field has a non-trivial curl and divergence"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ=1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1431,7 +1447,7 @@ For spherical coordinates, $\Phi(r, \theta, \phi)=r \langle \sin\phi\cos\theta,\
|
||||
|
||||
The curl then will then be
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla\times{F} = \det \left[
|
||||
\begin{array}{}
|
||||
\hat{e}_r & r\sin\phi\hat{e}_\theta & r\hat{e}_\phi \\
|
||||
@ -1439,7 +1455,7 @@ $$~
|
||||
F_r & r\sin\phi F_\theta & r F_\phi
|
||||
\end{array}
|
||||
\right].
|
||||
~$$
|
||||
```
|
||||
|
||||
For a *radial* function $F = h(r)e_r$. (That is $F_r = h(r)$, $F_\theta=0$, and $F_\phi=0$. What is the curl of $F$?
|
||||
|
||||
@ -1449,6 +1465,6 @@ raw" ``\vec{0}``",
|
||||
raw" ``re_\phi``",
|
||||
raw" ``rh'(r)e_\phi``"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -14,8 +14,8 @@ using HCubature
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
import PyPlot
|
||||
pyplot()
|
||||
#import PyPlot
|
||||
#pyplot()
|
||||
|
||||
|
||||
const frontmatter = (
|
||||
@ -89,9 +89,9 @@ As with the one-dimensional case, $f$ is Riemann integrable over $R$ if the limi
|
||||
|
||||
When $f$ is Riemann integrable over a rectangular region $R$, we denote the limit by any of:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_R f(x) dV, \quad \iint_R fdV, \quad \iint_R f(x_1, \dots, x_n) dx_1 \cdot\cdots\cdot dx_n, \quad\iint_R f(\vec{x}) d\vec{x}.
|
||||
~$$
|
||||
```
|
||||
|
||||
A key fact, requiring proof, is:
|
||||
|
||||
@ -111,25 +111,25 @@ As with one-dimensional integrals, from the Riemann sum definition, several fami
|
||||
|
||||
|
||||
* For integrable $f$ and $g$ and constants $a$ and $b$:
|
||||
$$~
|
||||
```math
|
||||
\iint_R (af(x) + bg(x))dV = a\iint_R f(x)dV + b\iint_R g(x) dV.
|
||||
~$$
|
||||
```
|
||||
|
||||
**Disjoint:**
|
||||
|
||||
* If $R$ and $R'$ are *disjoint* rectangular regions (possibly sharing a boundary), then the integral over the union is defined by linearity:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_{R \cup R'} f(x) dV = \iint_R f(x)dV + \iint_{R'} f(x) dV.
|
||||
~$$
|
||||
```
|
||||
|
||||
**Monotonicity:**
|
||||
|
||||
* As $f$ is bounded, let $m \leq f(x) \leq M$ for all $x$ in $R$. Then
|
||||
|
||||
$$~
|
||||
```math
|
||||
m V(R) \leq \iint_R f(x) dV \leq MV(R).
|
||||
~$$
|
||||
```
|
||||
|
||||
* If $f$ and $g$ are integrable *and* $f(x) \leq g(x)$, then the integrals have the same property, namely $\iint_R f dV \leq \iint_R gdV$.
|
||||
|
||||
@ -234,7 +234,7 @@ The answer agrees with that known from the formula, $4 = (1/3)a^2 h$, but the a
|
||||
We might try integrating a function with a condition:
|
||||
|
||||
```julia; hold=true
|
||||
function f(x,y, r)
|
||||
function f(x, y, r)
|
||||
if x^2 + y^2 < r
|
||||
sqrt(z - x^2 + y^2)
|
||||
else
|
||||
@ -246,16 +246,11 @@ end
|
||||
**But** `hcubature` is **very** slow to integrate such functions. We will see our instincts are good -- this is the approach taken to discuss integrals over general regions -- but this is not practical here. There are two alternative approaches to be discussed: approach the integral *iteratively* or *transform* the circular region into a rectangular region and integrate. Before doing so, we discuss how the integral is developed for more general regions.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The approach above takes a nice smooth function and makes it non smooth at the boundary. In general this is not a good idea for numeric solutions, as many algorithms work better with assumptions of smoothness.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The approach above takes a nice smooth function and makes it non smooth at the boundary. In general this is not a good idea for numeric solutions, as many algorithms work better with assumptions of smoothness.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The `Quadrature` package provides a uniform interface for `QuadGK`, `HCubature`, and other numeric integration routines available in `Julia`.""")
|
||||
```
|
||||
!!! note
|
||||
The `Quadrature` package provides a uniform interface for `QuadGK`, `HCubature`, and other numeric integration routines available in `Julia`.
|
||||
|
||||
## Integrals over more general regions
|
||||
|
||||
@ -350,10 +345,10 @@ $I(x) = \int_{-2}^2 f(x,y) dy$. Like partial derivatives, this integrates in $y
|
||||
The question then: under what conditions will the three integrals be equal?
|
||||
|
||||
> [Fubini](https://math.okstate.edu/people/lebl/osu4153-s16/chapter10-ver1.pdf). Let $R \times S$ be a closed rectangular region in $R^n \times R^m$. Suppose $f$ is bounded. Define $f_x(y) = f(x,y)$ and $f^y(x) = f(x,y)$ where $x$ is in $R^n$ and $y$ in $R^m$. *If* $f_x$ and $f^y$ are integrable then
|
||||
> $$~
|
||||
> ```math
|
||||
> \iint_{R\times S}fdV = \iint_R \left(\iint_S f_x(y) dy\right) dx
|
||||
> = \iint_S \left(\iint_R f^y(x) dx\right) dy.
|
||||
> ~$$
|
||||
> ```
|
||||
|
||||
Similarly, if $f^y$ is integrable for all $y$, then $\iint_{R\times S}fdV =\iint_S \iint_R f(x,y) dx dy$.
|
||||
|
||||
@ -380,18 +375,18 @@ A domain, as described above, is known as a [normal](https://en.wikipedia.org/wi
|
||||
|
||||
For example, we return to the problem of a square pyramid, only now using symmetry, we integrate only over the triangular region between $0 \leq x \leq a/2$ and $0 \leq y \leq x$. The answer is then (the $8$ by symmetry)
|
||||
|
||||
$$~
|
||||
```math
|
||||
V = 8 \int_0^{a/2} \int_0^x h(l(x,y) - d(x,y))/l(x,y) dy dx.
|
||||
~$$
|
||||
```
|
||||
|
||||
But, using similar triangles, we have $d/x = l/(a/2)$ so $(l-d)/l = 1 - 2x/a$. Continuing, our answer becomes
|
||||
|
||||
$$~
|
||||
```math
|
||||
V = 8 \int_0^{a/2} (\int_0^x h(1-\frac{2x}{a}) dy) dx =
|
||||
8 \int_0^{a/2} (h(1-2x/a) \cdot x) dx =
|
||||
8 (hx^2_2 \big\lvert_{0}^{a/2} - \frac{2}{a}\frac{x^3}{3}\big\lvert_0^{a/2})=
|
||||
8 h(\frac{a^2}{8} - \frac{2}{24}a^2) = \frac{a^2h}{3}.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -402,9 +397,9 @@ The `integrate` function of `SymPy` uses various algorithms to symbolically inte
|
||||
|
||||
For example, to perform the integral
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_a^b \int_{h(x)}^{g(x)} f(x,y) dy dx
|
||||
~$$
|
||||
```
|
||||
|
||||
the call would look like:
|
||||
|
||||
@ -585,9 +580,9 @@ integrate(rho(x,y), (y, h(x), g(x)), (x, -a, a))
|
||||
|
||||
Integrate $\int_0^1 \int_y^1 \cos(x^2) dx dy$ avoiding the *impossible* integral of $\cos(x^2)$. As the integrand is continuous, Fubini's Theorem allows the interchange of the variable of integraton. The region, $R$, is a triangle in the first quadrant below the line $y=x$ and left of the line $x=1$. So we have:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_0^1 \int_0^x \cos(x^2) dy dx
|
||||
~$$
|
||||
```
|
||||
|
||||
We can integrate this, as the interior integral leaves $x \cos(x^2)$ to integrate:
|
||||
|
||||
@ -692,8 +687,9 @@ sin(1)/2
|
||||
|
||||
Triple integrals are identical in theory to double integrals, though the computations can be more involved and the regions more complicated to describe. The main regions (emphasized by Strang) to understand are: box, prism, cylinder, cone, tetrahedron, and sphere.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ts = range(0, pi/2, length=50)
|
||||
```julia; echo=false
|
||||
let
|
||||
ts = range(0, pi/2, length=50)
|
||||
O = [0,0,0]
|
||||
bx, by,bz = [1, 0, 0], [0,2,0], [0,0,3]
|
||||
|
||||
@ -748,7 +744,8 @@ ts = range(0, pi/2, length=50)
|
||||
push!(ps, p)
|
||||
|
||||
l = @layout [a b; c d; e]
|
||||
plot(ps..., layout=l)
|
||||
plot(ps..., layout=l)
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
@ -789,9 +786,9 @@ This is $1/6$th the volume of the box.
|
||||
|
||||
* Cone. Consider a cone formed by the function $z = f(x,y) = a - b(x^2+y^2)^{1/2}$ ($a,b > 0$) and the $x$-$y$ plane. This will have radius $r = a/b$ and height $a$. The volume is given by this integral:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_{x=-r}^r \int_{y=-\sqrt{r^2 - x^2}}^{\sqrt{r^2-x^2}} \int_0^{a - b(x^2 + y^2)} 1 dz dy dx.
|
||||
~$$
|
||||
```
|
||||
|
||||
This integral is doable, but `SymPy` has trouble with it. We will return to this when cylindrical coordinates are defined.
|
||||
|
||||
@ -799,9 +796,9 @@ This integral is doable, but `SymPy` has trouble with it. We will return to this
|
||||
|
||||
* Sphere. The sphere $x^2 + y^2 + z^2 \leq 1$ has a known volume. Can we compute it using integration? In Cartesian coordinates, we can describe the region $x^2 + y^2 \leq 1$ and then the $z$-limits will follow:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_{x=-1}^1 \int_{y=-\sqrt{1-x^2}}^{\sqrt{1-x^2}} \int_{z=-\sqrt{1 - x^2 - y^2}}^{\sqrt{1-x^2 - y^2}} 1 dz dy dx.
|
||||
~$$
|
||||
```
|
||||
|
||||
This integral is doable, but `SymPy` has trouble with it. We will return to this when spherical coordinates are defined.
|
||||
|
||||
@ -813,9 +810,9 @@ This integral is doable, but `SymPy` has trouble with it. We will return to this
|
||||
|
||||
The change of variables, or substitution, formula from first-semester calculus is expressed, under assumptions, by:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_{g(R)} f(x) dx = \int_R (f\circ g)(u)g'(u) du.
|
||||
~$$
|
||||
```
|
||||
|
||||
The derivation comes from reversing the chain rule. When using it, we start on the right hand side and typically write $x = g(u)$ and from here derive an expression involving differentials: $dx = g'(u) du$ and the rest follows. In practice, this is used to simplify the integrand in the search for an antiderivative, as $(f\circ g)$ is generally more complicated than $f$ alone.
|
||||
|
||||
@ -827,23 +824,23 @@ In [Katz](http://www.jstor.org/stable/2689856) a review of the history of "chang
|
||||
|
||||
We view $R$ in two coordinate systems $(x,y)$ and $(u,v)$. We have that
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
dx &= A du + B dv\\
|
||||
dy &= C du + D dv,
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
where $A = \partial{x}/\partial{u}$, $B = \partial{x}/\partial{v}$, $C= \partial{y}/\partial{u}$, and $D = \partial{y}/\partial{v}$. Lagrange, following Euler, first sets $x$ to be constant (as is done in iterated integration). Hence, $dx = 0$ and so $du = -C(B/A) dv$ and, after substitution, $dy = (D-C(B/A))dv$. Then Lagrange set $y$ to be a constant, so $dy = 0$ and hence $dv=0$ so $dx = Adu$. The area "element" $dx dy = A du \cdot (D - (B/A)) dv = (AD - BC) du dv$. Since areas and volumes are non-negative, the absolute value is used. With this, we have "$dxdy = |AD-BC|du dv$" as the analog of $dx = g'(u) du$.
|
||||
|
||||
The expression $AD - BC$ was also derived by Euler, by related means. Lagrange extended the analysis to 3 dimensions. Before doing so, it is helpful to understand the problem from a geometric perspective. Euler was attempting to understand the effects of the following change of variable:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
x &= a + mt + \sqrt{1-m^2} v\\
|
||||
y & = b + \sqrt{1-m^2}t -mv
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
Euler knew this to be a clockwise *rotation* by an angle $\theta$ with $\cos(\theta) = m$, a *reflection* through the $x$ axis, and a translation by $\langle a, b\rangle$. All these *should* preserve the area represented by $dx dy$, so he was *expecting* $dx dy = dt dv$.
|
||||
|
||||
@ -937,7 +934,7 @@ showG(G, 1, 1)
|
||||
The arrows are the images of the standard unit vectors. We see some transformations leave these *orthogonal* and some change the respective lengths.
|
||||
The area of the associated parallelogram can be found using the determinant of an accompanying matrix. For two dimensions, using the cross product formulation on the embedded vectors, the area is
|
||||
|
||||
$$~
|
||||
```math
|
||||
\| \det\left(\left[
|
||||
\begin{array}{}
|
||||
\hat{i} & \hat{j} & \hat{k}\\
|
||||
@ -961,7 +958,7 @@ v_1 & v_2
|
||||
\end{array}
|
||||
\right]
|
||||
\right)|.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
Using the fact that the two vectors involved are columns in the Jacobian of the transformation, this is just $|\det(J_G)|$. For $3$ dimensions, the determinant gives the volume of the 3-dimensional parallelepiped in the same manner. This holds for higher dimensions.
|
||||
@ -970,20 +967,16 @@ The absolute value of the determinant of the Jacobian
|
||||
is the multiplying factor that is seen in the change of variable formula for all dimensions:
|
||||
|
||||
> [Change of variable](https://en.wikipedia.org/wiki/Integration_by_substitution#Substitution_for_multiple_variables) Let $U$ be an open set in $R^n$, $G:U \rightarrow R^n$ be an *injective* differentiable function with *continuous* partial derivatives. If $f$ is continuous and compactly supported, then
|
||||
> $$~
|
||||
> ```math
|
||||
> \iint_{G(S)} f(\vec{x}) dV = \iint_S (f \circ G)(\vec{u}) |\det(J_G)(\vec{u})| dU.
|
||||
> ~$$
|
||||
> ```
|
||||
|
||||
|
||||
For the one-dimensional case, there is no absolute value, but there the interval is reversed, producing "negative" area. This is not the case here, where $S$ is parameterized to give positive volume.
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
!!! note
|
||||
The term "functional determinant" is found for the value $\det(J_G)$, as is the notation $\partial(x_1, x_2, \dots x_n)/\partial(u_1, u_2, \dots, u_n)$.
|
||||
|
||||
The term "functional determinant" is found for the value $\det(J_G)$, as is the notation $\partial(x_1, x_2, \dots x_n)/\partial(u_1, u_2, \dots, u_n)$.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
### Two dimensional change of variables
|
||||
|
||||
@ -994,14 +987,14 @@ Now we see several examples of two-dimensional transformations.
|
||||
|
||||
We have [seen](../differentiable_vector_calculus/polar_coordinates.html) how to compute area in polar coordinates through the formula $A = \int (1/2) r^2(\theta) d\theta$. This formula can be derived as follows. Consider a region $R$ parameterized in polar coordinates by $r(\theta)$ for $a \leq \theta \leq b$. The area of this region would be $\iint_R fdA$. Let $G(r, \theta) = r \langle \cos\theta, \sin\theta\rangle$. Then
|
||||
|
||||
$$~
|
||||
```math
|
||||
J_G = \left[
|
||||
\begin{array}{}
|
||||
\cos(\theta) & - r\sin(\theta)\\
|
||||
\sin(\theta) & r\cos(\theta)
|
||||
\end{array}
|
||||
\right],
|
||||
~$$
|
||||
```
|
||||
|
||||
with determinant $r$.
|
||||
|
||||
@ -1010,9 +1003,9 @@ That is, for *polar coordinates* $dx dy = r dr d\theta$ ($r \geq 0$).
|
||||
|
||||
So by the change of variable formula, we have:
|
||||
|
||||
$$~
|
||||
```math
|
||||
A = \iint_R 1 dx dy = \int_a^b \int_0^{r(\theta)} 1 r dr d\theta = \int_a^b \frac{r^2(\theta)}{2} d\theta.
|
||||
~$$
|
||||
```
|
||||
|
||||
The key is noting that the region, $S$, described by $\theta$ running from $a$ to $b$ and $r$ running from $0$ to $r(\theta)$, maps onto $R$ through the change of variables. As polar coordinates is just a renaming, this is clear to see.
|
||||
|
||||
@ -1020,21 +1013,21 @@ The key is noting that the region, $S$, described by $\theta$ running from $a$ t
|
||||
|
||||
Now consider finding the volume of a sphere using polar coordinates. We have, with $\rho$ being the radius:
|
||||
|
||||
$$~
|
||||
```math
|
||||
V = 2 \iint_R \sqrt{\rho^2 - x^2 - y^2} dy dx,
|
||||
~$$
|
||||
```
|
||||
|
||||
where $R$ is the disc of radius $\rho$. Using polar coordinates, we have $x^2 + y^2 = r^2$ and the expression becomes:
|
||||
|
||||
$$~
|
||||
```math
|
||||
V = 2 \int_0^{2\pi} \int_0^\rho \sqrt{\rho^2 - r^2} r dr d\theta = 2 \int_0^{2\pi} -(1 - r^2)^{3/2}\frac{1}{3} \mid_0^\rho d\theta = 2\int_0^{2\pi} \frac{\rho^3}{3}d\theta = \frac{4\pi\rho^3}{3}.
|
||||
~$$
|
||||
```
|
||||
|
||||
##### Linear transformations
|
||||
|
||||
Some [transformations](https://en.wikipedia.org/wiki/Transformation_matrix#Examples_in_2D_computer_graphics) from ``2``D computer graphics are represented in matrix notation:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\left[
|
||||
\begin{array}{}
|
||||
x\\
|
||||
@ -1053,7 +1046,7 @@ u\\
|
||||
v
|
||||
\end{array}
|
||||
\right],
|
||||
~$$
|
||||
```
|
||||
|
||||
or $G(u,v) = \langle au+bv, cu+dv\rangle$. The Jacobian of this *linear* transformation is the matrix itself.
|
||||
|
||||
@ -1085,7 +1078,7 @@ showG(G)
|
||||
|
||||
* **Reflection** If $\vec{l} = \langle l_x, l_y \rangle$ with norm $\|\vec{l}\|$. The reflection through the line in the direction of $\vec{l}$ through the origin is defined, using a matrix, by:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\frac{1}{\| \vec{l} \|^2}
|
||||
\left[
|
||||
\begin{array}{}
|
||||
@ -1093,7 +1086,7 @@ l_x^2 - l_y^2 & 2 l_x l_y\\
|
||||
2l_x l_y & l_y^2 - l_x^2
|
||||
\end{array}
|
||||
\right]
|
||||
~$$
|
||||
```
|
||||
|
||||
For some simple cases: $\langle l_x, l_y \rangle = \langle 1, 1\rangle$, the diagonal, this is $G(u,v) = (1/2) \langle 2v, 2u \rangle$; $\langle l_x, l_y \rangle = \langle 0, 1\rangle$ (the $y$-axis) this is $G(u,v) = \langle -u, v\rangle$.
|
||||
|
||||
@ -1126,7 +1119,7 @@ showG(G, lambda=1/3)
|
||||
|
||||
The determinant of the Jacobian is
|
||||
|
||||
$$~
|
||||
```math
|
||||
\det(J_G) = \det\left(
|
||||
\left[
|
||||
\begin{array}{}
|
||||
@ -1135,12 +1128,12 @@ v & u
|
||||
\end{array}
|
||||
\right]
|
||||
\right) = u.
|
||||
~$$
|
||||
```
|
||||
|
||||
So, $\iint_R f(x,y) dA = \int_0^1\int_0^1 f(u, uv) u du dv$. Here we illustrate with a generic monomial:
|
||||
|
||||
```julia;
|
||||
@syms n::positive m::positive
|
||||
@syms x y n::positive m::positive
|
||||
monomial(x,y) = x^n*y^m
|
||||
integrate(monomial(x,y), (y, 0, x), (x, 0, 1))
|
||||
```
|
||||
@ -1159,10 +1152,13 @@ What about other triangles, say the triangle bounded by $x=0$, $y=0$ and $y-x=1$
|
||||
|
||||
This can be seen as a reflection through the line $x=1/2$ of the triangle above. If $G_1$ represents the mapping from $U [0,1]\times[0,1]$ into the triangle of the last problem, and $G_2$ represents the reflection through the line $x=1/2$, then the transformation $G_2 \circ G_1$ will map the box $U$ into the desired region. By the chain rule, we have:
|
||||
|
||||
$$~
|
||||
\int_{(G_2\circ G_1)(U))} f dx = \int_U (f\circ G_2 \circ G_1) |\det(J_{G_2 \circ G_1}| du =
|
||||
```math
|
||||
\begin{align*}
|
||||
\int_{(G_2\circ G_1)(U))} f dx &= \int_U (f\circ G_2 \circ G_1) |\det(J_{G_2 \circ G_1}| du \\
|
||||
&=
|
||||
\int_U (f\circ G_2 \circ G_1) |\det(J_{G_2}(G_1(u))||\det J_{G_1}(u)| du.
|
||||
~$$
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
(In [Katz](http://www.jstor.org/stable/2689856) it is mentioned that Jacobi showed this in 1841.)
|
||||
|
||||
@ -1255,34 +1251,34 @@ plot(ps..., layout=l)
|
||||
|
||||
The center of mass is a balancing point of a region with density $\rho(x,y)$. In two dimensions it is a point $\langle \bar{x}, \bar{y}\rangle$. These are found by the following formulas:
|
||||
|
||||
$$~
|
||||
```math
|
||||
A = \iint_R \rho(x,y) dA, \quad \bar{x} = \frac{1}{A} \iint_R x \rho(x,y) dA, \quad
|
||||
\bar{y} = \frac{1}{A} \iint_R y \rho(x,y) dA.
|
||||
~$$
|
||||
```
|
||||
|
||||
The $x$ value can be seen in terms of Fubini by integrating in $y$ first:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_R x \rho(x,y) dA = \int_{x=a}^b (\int_{y=h(x)}^{g(x)} \rho(x,y) dy) dx.
|
||||
~$$
|
||||
```
|
||||
|
||||
The inner integral is the mass of a slice at a value along the $x$ axis. The center of mass is formed then by the mass times the distance from the origin. The center of mass is a "balance" point, in the sense that $\iint_R (x - \bar{x}) dA = 0$ and $\iint_R (y-\bar{y})dA = 0$.
|
||||
|
||||
For example, the center of mass of the upper half *unit* disc will have a centroid with $\bar{x} = 0$, by symmetry. We can see this by integrating in *Cartesian* coordinates, as follows
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_R x dA = \int_{y=0}^1 \int_{x=-\sqrt{1-y^2}}^{\sqrt{1 - y^2}} x dx dy.
|
||||
~$$
|
||||
```
|
||||
|
||||
The inner integral is $0$ as it an integral of an *odd* function over an interval symmetric about $0$.
|
||||
|
||||
|
||||
The value of $\bar{y}$ is found using polar coordinate transformation from:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_R y dA = \int_{r=0}^1 \int_{\theta=0}^{\pi} (r\sin(\theta))r d\theta dr =
|
||||
\int_{r=0}^1 r^2 dr \int_{\theta=0}^{\pi}\sin(\theta) = \frac{1}{3} \cdot 2.
|
||||
~$$
|
||||
```
|
||||
|
||||
The third equals sign uses separability. The answer for $\bar{ is this value divided by the area, or $2/(3\pi)$.
|
||||
|
||||
@ -1294,9 +1290,9 @@ Let $R$ be the half disc contained by $x^2 + y^2 = 1$ and $y \geq 0$. Let $\rho(
|
||||
|
||||
$R$ is best described in polar coordinates, so we try to compute
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_0^1 \int_{-\pi/2}^{\pi/2} (r\cos(\theta))^2 (r\cos(\theta))(r\sin(\theta)) r d\theta dr.
|
||||
~$$
|
||||
```
|
||||
|
||||
That requires integrating $\sin^2(\theta)\cos^3(\theta)$, a doable task, but best left to SymPy:
|
||||
|
||||
@ -1314,9 +1310,9 @@ integrate(x^2 * rho(x, y), (theta, -PI/2, PI/2), (r, 0, 1))
|
||||
|
||||
The counterclockwise rotation of the unit square is $G(u,v) = \langle \cos(\alpha)u-\sin(\alpha)v, \sin(\alpha)u + \cos(\alpha) v\rangle$. This comes from the above formula for clockwise rotation using $-\alpha$. This transformation has Jacobian determinant $1$, as the area is not deformed. With this, we have
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_R x^2 dA = \iint_{G(U)} (f\circ G)(u) |\det(J_G(u))| dU,
|
||||
~$$
|
||||
```
|
||||
|
||||
which is computed with:
|
||||
|
||||
@ -1334,9 +1330,9 @@ Let $R$ be a ring with inner radius $4$ and outer radius $5$. Find its moment of
|
||||
|
||||
The integral to compute is:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_R x^2 dA,
|
||||
~$$
|
||||
```
|
||||
|
||||
with domain that is easy to describe in polar coordinates:
|
||||
|
||||
@ -1356,9 +1352,9 @@ The change of variables formula is no different between dimensions $2$ and $3$ (
|
||||
|
||||
Polar coordinates describe the $x$-$y$ plane in terms of a radius $r$ and angle $\theta$. *Cylindrical* coordinates describe the $x-y-z$ plane in terms of $r, \theta$, and $z$. A transformation is:
|
||||
|
||||
$$~
|
||||
```math
|
||||
G(r,\theta, z) = \langle r\cos(\theta), r\sin(\theta), z\rangle.
|
||||
~$$
|
||||
```
|
||||
|
||||
This has Jacobian determinant $r$, similar to polar coordinates.
|
||||
|
||||
@ -1368,18 +1364,18 @@ This has Jacobian determinant $r$, similar to polar coordinates.
|
||||
|
||||
Returning to the volume of a cone above the $x$-$y$ plane under $z = a - b(x^2 + y^2)^{12}$. This yielded the integral in Cartesian coordinates:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_{x=-r}^r \int_{y=-\sqrt{r^2 - x^2}}^{\sqrt{r^2-x^2}} \int_0^{a - b(x^2 + y^2)} 1 dz dy dx,
|
||||
~$$
|
||||
```
|
||||
|
||||
where $r=a/b$. This is *much* simpler in Cylindrical coordinates, as the region is described by the rectangle in $(r, \theta)$: $[0, \sqrt{b/a}] \times [0, 2\pi]$ and the $z$ range is from $0$ to $a - b r$.
|
||||
|
||||
The volume then is:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_{theta=0}^{2\pi} \int_{r=0}^{a/b} \int_{z=0}^{a - br} 1 r dz dr d\theta =
|
||||
2\pi \int_{r=0}^{a/b} (a-br)r dr = \frac{\pi a^3}{3b^2}.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
This is in agreement with $\pi r^2 h/3$.
|
||||
@ -1437,13 +1433,13 @@ Spherical coordinates describe a point in space by a radius from the origin, $r$
|
||||
|
||||
The exact formula to relate $(\rho, \theta, \phi)$ to $(x,y,z)$ is given by
|
||||
|
||||
$$~
|
||||
```math
|
||||
G(\rho, \theta, \phi) = \rho \langle
|
||||
\sin(\phi)\cos(\theta),
|
||||
\sin(\phi)\sin(\theta),
|
||||
\cos(\phi)
|
||||
\rangle.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
@ -1465,10 +1461,10 @@ det(G(ρ, theta, phi).jacobian([ρ, theta, phi])) |> simplify |> abs
|
||||
|
||||
Computing the volume of a sphere is a challenge (for SymPy) in Cartesian coordinates, but a breeze in spherical coordinates. Using $r^2\sin(\phi)$ as the multiplying factor, the volume is simply:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_{\theta=0}^{2\pi} \int_{\phi=0}^{\pi} \int_{r=0}^R 1 \cdot r^2 \sin(\phi) dr d\phi d\theta =
|
||||
\int_{\theta=0}^{2\pi} d\theta \int_{\phi=0}^{\pi} \sin(\phi)d\phi \int_{r=0}^R r^2 dr = (2\pi)(2)\frac{R^3}{3} = \frac{4\pi R^3}{3}.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -1478,9 +1474,9 @@ Compute the volume of the ellipsoid, $R$, described by $(x/a)^2 + (y/v)^2 + (z/c
|
||||
|
||||
We first change variables via $G(u,v,w) = \langle ua, vb, wc \rangle$. This maps the unit sphere, $S$, given by $u^2 + v^2 + w^2 \leq 1$ into the ellipsoid. Then
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_R 1 dV = \iint_S 1 |\det(J_G)| dU
|
||||
~$$
|
||||
```
|
||||
|
||||
But the Jacobian is a constant:
|
||||
|
||||
@ -1499,17 +1495,17 @@ So the answer is $abc V(S) = 4\pi abc/3$
|
||||
|
||||
Suppose $f(x,y) = f_1(x)f_2(y)$ and $R = [a_1, b_1] \times [a_2,b_2]$ is a rectangular region. Is this true?
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_R f dA = (\int_{a_1}^{b_1} f_1(x) dx) \cdot (\int_{a_2}^{b_2} f_2(y) dy).
|
||||
~$$
|
||||
```
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [
|
||||
L"Yes. As an inner integral $\int_{a^2}^{b_2} f(x,y) dy = f_1(x) \int_{a_2}^{b_2} f_2(y) dy$.",
|
||||
"No."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1517,9 +1513,9 @@ radioq(choices, ans)
|
||||
|
||||
Which integrals of the following are $0$ by symmetry? Let $R$ be the unit disc.
|
||||
|
||||
$$~
|
||||
```math
|
||||
a = \iint_R x dA, \quad b = \iint_R (x^2 + y^2) dA, \quad c = \iint_R xy dA
|
||||
~$$
|
||||
```
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [
|
||||
@ -1527,8 +1523,8 @@ L"Both $a$ and $b$",
|
||||
L"Both $a$ and $c$",
|
||||
L"Both $b$ and $c$"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1536,11 +1532,11 @@ radioq(choices, ans)
|
||||
|
||||
Let $R$ be the unit disc. Which integrals can be found from common geometric formulas (e.g., known formulas for the sphere, cone, pyramid, ellipse, ...)
|
||||
|
||||
$$~
|
||||
```math
|
||||
a = \iint_R (1 - (x^2+y2)) dA, \quad
|
||||
b = \iint_R (1 - \sqrt{x^2 + y^2}) dA, \quad
|
||||
c = \iint_R (1 - (x^2 + y^2)^2 dA
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
@ -1549,8 +1545,8 @@ L"Both $a$ and $b$",
|
||||
L"Both $a$ and $c$",
|
||||
L"Both $b$ and $c$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1567,8 +1563,8 @@ raw" ``\int_0^1 \int_0^{(1-x^3)^{1/3}} 1\cdot dy dx``",
|
||||
raw" ``\int_0^1 \int_0^{(1-y^3)^{1/3}} 1\cdot dx dy``",
|
||||
raw" ``\int_0^1 \int_0^{(1-y^3)^{1/3}} 1\cdot dy dx``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1583,8 +1579,8 @@ raw" ``\int_0^b\int_{y/b}^{2-y/b} dx dy``",
|
||||
raw" ``\int_0^2\int_0^{bx} dy dx``",
|
||||
raw" ``\int_0^2 \int_0^{2b - bx} dy dx``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1598,8 +1594,8 @@ raw" ``\int_a^b \int_0^{f(x)} dy dx``",
|
||||
raw" ``\int_a^b \int_0^{f(x)} dx dy``",
|
||||
raw" ``\int_0^{f(x)} \int_a^b dx dy``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1613,8 +1609,8 @@ raw" ``G(u,v) = \langle u-v, u+v \rangle``",
|
||||
raw" ``G(u,v) = \langle u^2-v^2, u^2+v^2 \rangle``",
|
||||
raw" ``G(u,v) = \langle u-v, u \rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1636,12 +1632,12 @@ Let $G(u, v) = \langle \cosh(u)\cos(v), \sinh(u)\sin(v) \rangle$. Compute the de
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [
|
||||
raw" ``\sin^{2}{\left (v \right )} \cosh^{2}{\left (u \right )} + \cos^{2}{\left (v \right )} \sinh^{2}{\left (u \right )}",
|
||||
raw" ``\sin^{2}{\left (v \right )} \cosh^{2}{\left (u \right )} + \cos^{2}{\left (v \right )} \sinh^{2}{\left (u \right )}``",
|
||||
raw" ``1``",
|
||||
raw" ``\sinh(u)\cosh(v)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1655,8 +1651,8 @@ L"It is $1$, as each is area preserving",
|
||||
L"It is $r$, as the rotation uses polar coordinates",
|
||||
L"It is $r^2 \sin(\phi)$, as the rotations use spherical coordinates"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1681,8 +1677,8 @@ L"The value $\bar{x}$ of the centroid",
|
||||
L"The value $\bar{y}$ of the centroid",
|
||||
L"The moment of inertia of $R$ about the $x$ axis"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
What does $B/A$ compute?
|
||||
@ -1695,8 +1691,8 @@ L"The value $\bar{x}$ of the centroid",
|
||||
L"The value $\bar{y}$ of the centroid",
|
||||
L"The moment of inertia of $R$ about the $x$ axis"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1710,6 +1706,6 @@ raw" ``dtdv``",
|
||||
raw" ``(1-2m^2)dt dv``",
|
||||
raw" ``m\sqrt{1-m^2}dt^2+(1-2m^2)dtdv -m\sqrt{1-m^2}dv^2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -242,11 +242,9 @@ quadgk(t -> (Fₘ ∘ rₒ)(t) ⋅ rₒ'(t), 0, 1)
|
||||
|
||||
Still $0$. We will see next that this is not surprising if something about $F$ is known.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The [Washington Post](https://www.washingtonpost.com/outlook/everything-you-thought-you-knew-about-gravity-is-wrong/2019/08/01/627f3696-a723-11e9-a3a6-ab670962db05_story.html") had an article by Richard Panek with the quote "Well, yes — depending on what we mean by 'attraction.' Two bodies of mass don’t actually exert some mysterious tugging on each other. Newton himself tried to avoid the word 'attraction' for this very reason. All (!) he was trying to do was find the math to describe the motions both down here on Earth and up there among the planets (of which Earth, thanks to Copernicus and Kepler and Galileo, was one)." The point being the formula above is a mathematical description of the force, but not an explanation of how the force actually is transferred.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The [Washington Post](https://www.washingtonpost.com/outlook/everything-you-thought-you-knew-about-gravity-is-wrong/2019/08/01/627f3696-a723-11e9-a3a6-ab670962db05_story.html") had an article by Richard Panek with the quote "Well, yes — depending on what we mean by 'attraction.' Two bodies of mass don’t actually exert some mysterious tugging on each other. Newton himself tried to avoid the word 'attraction' for this very reason. All (!) he was trying to do was find the math to describe the motions both down here on Earth and up there among the planets (of which Earth, thanks to Copernicus and Kepler and Galileo, was one)." The point being the formula above is a mathematical description of the force, but not an explanation of how the force actually is transferred.
|
||||
|
||||
|
||||
#### Work in a *conservative* vector field
|
||||
|
||||
@ -432,11 +430,8 @@ p
|
||||
The flow integral is typically computed for a closed (Jordan) curve, measuring the total flow out of a region. In this case, the integral is written $\oint_C (F\cdot\hat{N})ds$.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
For a Jordan curve, the positive orientation of the curve is such that the normal direction (proportional to $\hat{T}'$) points away from the bounded interior. For a non-closed path, the choice of parameterization will determine the normal and the integral for flow across a curve is dependent - up to its sign - on this choice.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
For a Jordan curve, the positive orientation of the curve is such that the normal direction (proportional to $\hat{T}'$) points away from the bounded interior. For a non-closed path, the choice of parameterization will determine the normal and the integral for flow across a curve is dependent - up to its sign - on this choice.
|
||||
|
||||
|
||||
##### Example
|
||||
@ -725,10 +720,10 @@ In [Surface area](../integrals/surface_area.mmd) the following formula for the s
|
||||
|
||||
Consider the transformation $(x, \theta) \rightarrow \langle x, f(x)\cos(\theta), f(x)\sin(\theta)$. This maps the region $[a,b] \times [0, 2\pi]$ *onto* the surface of revolution. As such, the surface element would be:
|
||||
|
||||
```julia; hold=true
|
||||
@syms f()::positive x::real theta::real
|
||||
```julia
|
||||
@syms 𝒇()::positive x::real theta::real
|
||||
|
||||
Phi(x, theta) = [x, f(x)*cos(theta), f(x)*sin(theta)]
|
||||
Phi(x, theta) = [x, 𝒇(x)*cos(theta), 𝒇(x)*sin(theta)]
|
||||
Jac = Phi(x, theta).jacobian([x, theta])
|
||||
v1, v2 = Jac[:,1], Jac[:,2]
|
||||
se = norm(v1 × v2)
|
||||
@ -994,8 +989,8 @@ raw" ``\langle a, b, c\rangle / \| \langle a, b, c\rangle\|``",
|
||||
raw" ``\langle a, b, c\rangle``",
|
||||
raw" ``\langle d-a, d-b, d-c\rangle / \| \langle d-a, d-b, d-c\rangle\|``",
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Does it depend on $d$?
|
||||
@ -1006,8 +1001,8 @@ L"No. Moving $d$ just shifts the plane up or down the $z$ axis, but won't change
|
||||
L"Yes. Of course. Different values for $d$ mean different values for $x$, $y$, and $z$ are needed.",
|
||||
L"Yes. The gradient of $F(x,y,z) = ax + by + cz$ will be normal to the level curve $F(x,y,z)=d$, and so this will depend on $d$."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1035,8 +1030,8 @@ raw" ``2\pi + 2\pi^2``",
|
||||
raw" ``2\pi^2``",
|
||||
raw" ``4\pi``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1062,8 +1057,8 @@ choices =[
|
||||
L"It will be $0$, as $\nabla{f}$ is orthogonal to the level curve and $\vec{r}'$ is tangent to the level curve",
|
||||
L"It will $f(b)-f(a)$ for any $b$ or $a$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1103,8 +1098,8 @@ choices = [
|
||||
L"The field is a potential field, but the path integral around $0$ is not path dependent.",
|
||||
L"The value of $d/dt(f\circ\vec{r})=0$, so the integral should be $0$."
|
||||
]
|
||||
ans =1
|
||||
radioq(choices, ans)
|
||||
answ =1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
The function $F = \nabla{f}$ is
|
||||
@ -1114,8 +1109,8 @@ choices = [
|
||||
"Not continuous everywhere",
|
||||
"Continuous everywhere"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1165,8 +1160,8 @@ raw" ``\int_0^{2\pi} (a\cos(t)) \cdot (b\cos(t)) dt``",
|
||||
raw" ``\int_0^{2\pi} (-b\sin(t)) \cdot (b\cos(t)) dt``",
|
||||
raw" ``\int_0^{2\pi} (a\cos(t)) \cdot (a\cos(t)) dt``"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1182,8 +1177,8 @@ raw" ``\langle \cos(v), \sin(v), 1\rangle``",
|
||||
raw" ``\langle -u\sin(v), u\cos(v), 0\rangle``",
|
||||
raw" ``u\langle -\cos(v), -\sin(v), 1\rangle``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
Compute $\vec{v}_2 = \partial{\Phi}/\partial{u}$
|
||||
@ -1194,8 +1189,8 @@ raw" ``\langle \cos(v), \sin(v), 1\rangle``",
|
||||
raw" ``\langle -u\sin(v), u\cos(v), 0\rangle``",
|
||||
raw" ``u\langle -\cos(v), -\sin(v), 1\rangle``"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
Compute $\vec{v}_1 \times \vec{v}_2$
|
||||
@ -1207,8 +1202,8 @@ raw" ``\langle \cos(v), \sin(v), 1\rangle``",
|
||||
raw" ``\langle -u\sin(v), u\cos(v), 0\rangle``",
|
||||
raw" ``u\langle -\cos(v), -\sin(v), 1\rangle``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1288,8 +1283,8 @@ raw" ``\sqrt{2}/24``",
|
||||
raw" ``2/\sqrt{24}``",
|
||||
raw" ``1/12``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1315,6 +1310,6 @@ raw" ``0``",
|
||||
raw" ``7/36``",
|
||||
raw" ``1/60``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -114,24 +114,24 @@ Let's consider now what an integral over the boundary would mean. The region, or
|
||||
|
||||
With this choice of integral over the boundary, we can see much cancellation arises were we to compute this integral for each piece, as we would have with $a=x_0 < x_1 < \cdots x_{n-1} < x_n=b$:
|
||||
|
||||
$$~
|
||||
```math
|
||||
(F(x_1) - F(x_0)) + (F(x_2)-F(x_1)) + \cdots + (F(x_n) - F(x_{n-1})) = F(x_n) - F(x_0) = F(b) - F(a).
|
||||
~$$
|
||||
```
|
||||
|
||||
That is, with this definition for a boundary integral, the interior pieces of the microscopic approximation cancel and the total is just the integral over the oriented macroscopic boundary $\{a, b\}$.
|
||||
|
||||
But each microscopic piece can be reimagined, as
|
||||
|
||||
$$~
|
||||
```math
|
||||
F(x_{i}) - F(x_{i-1}) = \left(\frac{F(x_{i}) - F(x_{i-1})}{\Delta{x}}\right)\Delta{x}
|
||||
\approx F'(x_i)\Delta{x}.
|
||||
~$$
|
||||
```
|
||||
|
||||
The approximation could be exact were the mean value theorem used to identify a point in the interval, but we don't pursue that, as the key point is the right hand side is a Riemann sum approximation for a *different* integral, in this case the integral $\int_a^b F'(x) dx$. Passing from the microscopic view to an infinitesimal view, the picture gives two interpretations, leading to the Fundamental Theorem of Calculus:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_a^b F'(x) dx = F(b) - F(a).
|
||||
~$$
|
||||
```
|
||||
|
||||
The three theorems of this section, Green's theorem, Stokes' theorem, and the divergence theorem, can all be seen in this manner: the sum of microscopic boundary integrals leads to a macroscopic boundary integral of the entire region; whereas, by reinterpretation, the microscopic boundary integrals are viewed as Riemann sums, which in the limit become integrals of a *related* function over the region.
|
||||
|
||||
@ -166,14 +166,14 @@ p
|
||||
|
||||
Consider the boundary integral $\oint_c F\cdot\vec{T} ds$ around the smallest (green) squares. We have seen that the *curl* at a point in a direction is given in terms of the limit. Let the plane be the $x-y$ plane, and the $\hat{k}$ direction be the one coming out of the figure. In the derivation of the curl, we saw that the line integral for circulation around the square satisfies:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\lim \frac{1}{\Delta{x}\Delta{y}} \oint_C F \cdot\hat{T}ds =
|
||||
\frac{\partial{F_y}}{\partial{x}} - \frac{\partial{F_x}}{\partial{y}}.
|
||||
~$$
|
||||
```
|
||||
|
||||
If the green squares are small enough, then the line integrals satisfy:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\oint_C F \cdot\hat{T}ds
|
||||
\approx
|
||||
\left(
|
||||
@ -181,15 +181,15 @@ $$~
|
||||
-
|
||||
\frac{\partial{F_x}}{\partial{y}}
|
||||
\right) \Delta{x}\Delta{y} .
|
||||
~$$
|
||||
```
|
||||
|
||||
We interpret the right hand side as a Riemann sum approximation for the $2$ dimensional integral of the function $f(x,y) = \frac{\partial{F_x}}{\partial{y}} - \frac{\partial{F_y}}{\partial{x}}=\text{curl}(F)$, the two-dimensional curl. Were the green squares continued to fill out the large blue square, then the sum of these terms would approximate the integral
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iint_S f(x,y) dA = \iint_S
|
||||
\left(\frac{\partial{F_y}}{\partial{x}} - \frac{\partial{F_x}}{\partial{y}}\right) dA
|
||||
= \iint_S \text{curl}(F) dA.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
However, the microscopic boundary integrals have cancellations that lead to a macroscopic boundary integral. The sum of $\oint_C F \cdot\hat{T}ds$ over the $4$ green squares will be equal to $\oint_{C_r} F\cdot\hat{T}ds$, where $C_r$ is the red square, as the interior line integral pieces will all cancel off. The sum of $\oint_{C_r} F \cdot\hat{T}ds$ over the $4$ red squares will equal $\oint_{C_b} F \cdot\hat{T}ds$, where $C_b$ is the oriented path around the blue square, as again the interior line pieces will cancel off. Etc.
|
||||
@ -217,10 +217,10 @@ Some examples, following Strang, are:
|
||||
|
||||
Let $F(x,y) = \langle -y, x\rangle$. Then $\frac{\partial{F_y}}{\partial{x}} - \frac{\partial{F_x}}{\partial{y}}=2$, so
|
||||
|
||||
$$~
|
||||
```math
|
||||
\frac{1}{2}\oint_C F\cdot\hat{T}ds = \frac{1}{2}\oint_C (xdy - ydx) =
|
||||
\iint_D dA = A(D).
|
||||
~$$
|
||||
```
|
||||
|
||||
This gives a means to compute the area of a region by integrating around its boundary.
|
||||
|
||||
@ -235,29 +235,29 @@ F(v) = F(v...)
|
||||
|
||||
r(t) = [a*cos(t),b*sin(t)]
|
||||
|
||||
@syms a::positive b::positive
|
||||
@syms a::positive b::positive t
|
||||
(1//2) * integrate( F(r(t)) ⋅ diff.(r(t),t), (t, 0, 2PI))
|
||||
```
|
||||
|
||||
To compute the area of the triangle with vertices $(0,0)$, $(a,0)$ and $(0,b)$ we can orient the boundary counter clockwise. Let $A$ be the line segment from $(0,b)$ to $(0,0)$, $B$ be the line segment from $(0,0)$ to $(a,0)$, and $C$ be the other. Then
|
||||
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\frac{1}{2} \int_A F\cdot\hat{T} ds &=\frac{1}{2} \int_A -ydx = 0\\
|
||||
\frac{1}{2} \int_B F\cdot\hat{T} ds &=\frac{1}{2} \int_B xdy = 0,
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
as on $A$, $y=0$ and $dy=0$ and on $B$, $x=0$ and $dx=0$.
|
||||
|
||||
On $C$ we have $\vec{r}(t) = (0, b) + t\cdot(1,-b/a) =\langle t, b-(bt)/a\rangle$ from $t=a$ to $0$
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_C F\cdot \frac{d\vec{r}}{dt} dt =
|
||||
\int_a^0 \langle -b + (bt)/a), t\rangle\cdot\langle 1, -b/a\rangle dt
|
||||
= \int_a^0 -b dt = -bt\mid_{a}^0 = ba.
|
||||
~$$
|
||||
```
|
||||
|
||||
Dividing by $1/2$ give the familiar answer $A=(1/2) a b$.
|
||||
|
||||
@ -274,12 +274,17 @@ For the two dimensional case the curl is a scalar. *If* $F = \langle F_x, F_y\ra
|
||||
|
||||
Now assume $\partial{F_y}/\partial{x} - \partial{F_x}/\partial{y} = 0$. Let $P$ and $Q$ be two points in the plane. Take any path, $C_1$ from $P$ to $Q$ and any return path, $C_2$, from $Q$ to $P$ that do not cross and such that $C$, the concatenation of the two paths, satisfies Green's theorem. Then, as $F$ is continuous on an open interval containing $D$, we have:
|
||||
|
||||
$$~
|
||||
0 = \iint_D 0 dA =
|
||||
\iint_D \left(\partial{F_y}/\partial{x} - \partial{F_x}/\partial{y}\right)dA =
|
||||
\oint_C F \cdot \hat{T} ds =
|
||||
```math
|
||||
\begin{align*}
|
||||
0 &= \iint_D 0 dA \\
|
||||
&=
|
||||
\iint_D \left(\partial{F_y}/\partial{x} - \partial{F_x}/\partial{y}\right)dA \\
|
||||
&=
|
||||
\oint_C F \cdot \hat{T} ds \\
|
||||
&=
|
||||
\int_{C_1} F \cdot \hat{T} ds + \int_{C_2}F \cdot \hat{T} ds.
|
||||
~$$
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
Reversing $C_2$ to go from $P$ to $Q$, we see the two work integrals are identical, that is the field is conservative.
|
||||
|
||||
@ -293,14 +298,14 @@ For example, let $F(x,y) = \langle \sin(xy), \cos(xy) \rangle$. Is this a conser
|
||||
|
||||
We can check by taking partial derivatives. Those of interest are:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\frac{\partial{F_y}}{\partial{x}} &= \frac{\partial{(\cos(xy))}}{\partial{x}} =
|
||||
-\sin(xy) y,\\
|
||||
\frac{\partial{F_x}}{\partial{y}} &= \frac{\partial{(\sin(xy))}}{\partial{y}} =
|
||||
\cos(xy)x.
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
It is not the case that $\partial{F_y}/\partial{x} - \partial{F_x}/\partial{y}=0$, so this vector field is *not* conservative.
|
||||
|
||||
@ -326,9 +331,9 @@ diff(Fy, x) - diff(Fx, y) |> simplify
|
||||
|
||||
As the integrand is ``00``, $\iint_D \left( \partial{F_y}/{\partial{x}}-\partial{F_xy}/{\partial{y}}\right)dA = 0$, as well. But,
|
||||
|
||||
$$~
|
||||
```math
|
||||
F\cdot\hat{T} = \frac{R}{R\cdot{R}} \cdot \frac{R}{R\cdot{R}} = \frac{R\cdot{R}}{(R\cdot{R})^2} = \frac{1}{R\cdot{R}},
|
||||
~$$
|
||||
```
|
||||
|
||||
so $\oint_C F\cdot\hat{T}ds = 2\pi$, $C$ being the unit circle so $R\cdot{R}=1$.
|
||||
|
||||
@ -357,24 +362,24 @@ p
|
||||
|
||||
Let $A$ label the red line, $B$ the green curve, $C$ the blue line, and $D$ the black line. Then the area is given from Green's theorem by considering half of the the line integral of $F(x,y) = \langle -y, x\rangle$ or $\oint_C (xdy - ydx)$. To that matter we have:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\int_A (xdy - ydx) &= a f(a)\\
|
||||
\int_C (xdy - ydx) &= b(-f(b))\\
|
||||
\int_D (xdy - ydx) &= 0\\
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
Finally the integral over $B$, using integration by parts:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\int_B F(\vec{r}(t))\cdot \frac{d\vec{r}(t)}{dt} dt &=
|
||||
\int_b^a \langle -f(t),t)\rangle\cdot\langle 1, f'(t)\rangle dt\\
|
||||
&= \int_a^b f(t)dt - \int_a^b tf'(t)dt\\
|
||||
&= \int_a^b f(t)dt - \left(tf(t)\mid_a^b - \int_a^b f(t) dt\right).
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
Combining, we have after cancellation $\oint (xdy - ydx) = 2\int_a^b f(t) dt$, or after dividing by $2$ the signed area under the curve.
|
||||
|
||||
@ -403,16 +408,16 @@ The cut leads to a counter-clockwise orientation on the outer ring and a clockw
|
||||
|
||||
To see that the area integral of $F(x,y) = (1/2)\langle -y, x\rangle$ produces the area for this orientation we have, using $C_1$ as the outer ring, and $C_2$ as the inner ring:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\oint_{C_1} F \cdot \hat{T} ds &=
|
||||
\int_0^{2\pi} (1/2)(2)\langle -\sin(t), \cos(t)\rangle \cdot (2)\langle-\sin(t), \cos(t)\rangle dt
|
||||
= (1/2) (2\pi) 4 = 4\pi\\
|
||||
\int_0^{2\pi} (1/2)(2)\langle -\sin(t), \cos(t)\rangle \cdot (2)\langle-\sin(t), \cos(t)\rangle dt \\
|
||||
&= (1/2) (2\pi) 4 = 4\pi\\
|
||||
\oint_{C_2} F \cdot \hat{T} ds &=
|
||||
\int_{0}^{2\pi} (1/2) \langle \sin(t), \cos(t)\rangle \cdot \langle-\sin(t), -\cos(t)\rangle dt\\
|
||||
&= -(1/2)(2\pi) = -\pi.
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
(Using $\vec{r}(t) = 2\langle \cos(t), \sin(t)\rangle$ for the outer ring and $\vec{r}(t) = 1\langle \cos(t), -\sin(t)\rangle$ for the inner ring.)
|
||||
|
||||
@ -425,22 +430,22 @@ Green's theorem has a complement in terms of flow across $C$. As $C$ is positive
|
||||
|
||||
Let $F = \langle F_x, F_y \rangle$ and $G = \langle F_y, -F_x \rangle$, then $G\cdot\hat{T} = -F\cdot\hat{N}$. The curl formula applied to $G$ becomes
|
||||
|
||||
$$~
|
||||
```math
|
||||
\frac{\partial{G_y}}{\partial{x}} - \frac{\partial{G_x}}{\partial{y}} =
|
||||
\frac{\partial{-F_x}}{\partial{x}}-\frac{\partial{(F_y)}}{\partial{y}}
|
||||
=
|
||||
-\left(\frac{\partial{F_x}}{\partial{x}} + \frac{\partial{F_y}}{\partial{y}}\right)=
|
||||
-\nabla\cdot{F}.
|
||||
~$$
|
||||
```
|
||||
|
||||
Green's theorem applied to $G$ then gives this formula for $F$:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\oint_C F\cdot\hat{N} ds =
|
||||
-\oint_C G\cdot\hat{T} ds =
|
||||
-\iint_D (-\nabla\cdot{F})dA =
|
||||
\iint_D \nabla\cdot{F}dA.
|
||||
~$$
|
||||
```
|
||||
|
||||
The right hand side integral is the $2$-dimensional divergence, so this has the interpretation that the flux through $C$ ($\oint_C F\cdot\hat{N} ds$) is the integral of the divergence. (The divergence is defined in terms of a limit of this picture, so this theorem extends the microscopic view to a bigger view.)
|
||||
|
||||
@ -522,17 +527,17 @@ Again, the microscopic boundary integrals when added will give a macroscopic bou
|
||||
But, as seen in the derivation of the divergence, only modified for $2$ dimensions, we have
|
||||
$\nabla\cdot{F} = \lim \frac{1}{\Delta S} \oint_C F\cdot\hat{N}$, so for each cell
|
||||
|
||||
$$~
|
||||
```math
|
||||
\oint_{C_i} F\cdot\hat{N} \approx \left(\nabla\cdot{F}\right)\Delta{x}\Delta{y},
|
||||
~$$
|
||||
```
|
||||
an approximating Riemann sum for $\iint_D \nabla\cdot{F} dA$. This yields:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\oint_C (F \cdot\hat{N}) dA =
|
||||
\sum_i \oint_{C_i} (F \cdot\hat{N}) dA \approx
|
||||
\sum \left(\nabla\cdot{F}\right)\Delta{x}\Delta{y} \approx
|
||||
\iint_S \nabla\cdot{F}dA,
|
||||
~$$
|
||||
```
|
||||
|
||||
the approximation signs becoming equals signs in the limit.
|
||||
|
||||
@ -549,11 +554,11 @@ We have the divergence is simply $a + b$ so $\iint_D (a+b)dA = (a+b)A(D) = 4(a+b
|
||||
|
||||
The integral of the flow across $C$ consists of $4$ parts. By symmetry, they all should be similar. We consider the line segment connecting $(1,-1)$ to $(1,1)$ (which has the proper counterclockwise orientation):
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int_C F \cdot \hat{N} ds=
|
||||
\int_{-1}^1 \langle F_x, F_y\rangle\cdot\langle 0, 1\rangle ds =
|
||||
\int_{-1}^1 b dy = 2b.
|
||||
~$$
|
||||
```
|
||||
|
||||
Integrating across the top will give $2a$, along the bottom $2a$, and along the left side $2b$ totaling $4(a+b)$.
|
||||
|
||||
@ -586,10 +591,10 @@ The gradient of $f=\langle v_x, v_y\rangle$ is orthogonal to the contour lines o
|
||||
|
||||
As an [example](https://en.wikipedia.org/wiki/Potential_flow#Examples_of_two-dimensional_flows) consider the following in polar coordinates:
|
||||
|
||||
$$~
|
||||
```math
|
||||
f(r, \theta) = A r^n \cos(n\theta),\quad
|
||||
g(r, \theta) = A r^n \sin(n\theta).
|
||||
~$$
|
||||
```
|
||||
|
||||
The constant $A$ just sets the scale, the parameter $n$ has a qualitative effect on the contour lines. Consider $n=2$ visualized below:
|
||||
|
||||
@ -607,7 +612,7 @@ f(v) = f(v...); g(v)= g(v...)
|
||||
xs = ys = range(-2,2, length=50)
|
||||
p = contour(xs, ys, f∘Φ, color=:red, legend=false, aspect_ratio=:equal)
|
||||
contour!(p, xs, ys, g∘Φ, color=:blue, linewidth=3)
|
||||
pyplot()
|
||||
#pyplot()
|
||||
p
|
||||
```
|
||||
|
||||
@ -636,29 +641,34 @@ Imagine if instead of the retro labeling, a rectangular grid were drawn on the
|
||||
|
||||
Now imagine the popcorn expanding, but rather than worry about burning, focusing instead on what happens to the integral of the curl in the direction of the normal, we have
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla\times{F} \cdot\hat{N} = \lim \frac{1}{\Delta{S}} \oint_C F\cdot\hat{T} ds
|
||||
\approx \frac{1}{\Delta{S}} F\cdot\hat{T} \Delta{s}.
|
||||
~$$
|
||||
```
|
||||
|
||||
This gives the series of approximations:
|
||||
|
||||
$$~
|
||||
\oint_C F\cdot\hat{T} ds =
|
||||
\sum \oint_{C_i} F\cdot\hat{T} ds \approx
|
||||
\sum F\cdot\hat{T} \Delta s \approx
|
||||
\sum \nabla\times{F}\cdot\hat{N} \Delta{S} \approx
|
||||
```math
|
||||
\begin{align*}
|
||||
\oint_C F\cdot\hat{T} ds &=
|
||||
\sum \oint_{C_i} F\cdot\hat{T} ds \\
|
||||
&\approx
|
||||
\sum F\cdot\hat{T} \Delta s \\
|
||||
&\approx
|
||||
\sum \nabla\times{F}\cdot\hat{N} \Delta{S} \\
|
||||
&\approx
|
||||
\iint_S \nabla\times{F}\cdot\hat{N} dS.
|
||||
~$$
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
In terms of our expanding popcorn, the boundary integral - after accounting for cancellations, as in Green's theorem - can be seen as a microscopic sum of boundary integrals each of which is approximated by a term
|
||||
$\nabla\times{F}\cdot\hat{N} \Delta{S}$ which is viewed as a Riemann sum approximation for the the integral of the curl over the surface. The cancellation depends on a proper choice of orientation, but with that we have:
|
||||
|
||||
|
||||
> **Stokes' theorem**: Let $S$ be an orientable smooth surface in $R^3$ with boundary $C$, $C$ oriented so that the chosen normal for $S$ agrees with the right-hand rule for $C$'s orientation. Then *if* $F$ has continuous partial derivatives
|
||||
> $$~
|
||||
> ```math
|
||||
> \oint_C F \cdot\hat{T} ds = \iint_S (\nabla\times{F})\cdot\hat{N} dA.
|
||||
> ~$$
|
||||
> ```
|
||||
|
||||
|
||||
Green's theorem is an immediate consequence upon viewing the region in $R^2$ as a surface in $R^3$ with normal $\hat{k}$.
|
||||
@ -707,51 +717,51 @@ integrate(integrandₛ, (t, 0, 2PI))
|
||||
|
||||
Ampere's circuital law relates the line integral of the magnetic field to the induced current through:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\oint_C B\cdot\hat{T} ds = \mu_0 I.
|
||||
~$$
|
||||
```
|
||||
|
||||
The goal here is to re-express this integral law to produce a law at each point of the field. Let $S$ be a surface with boundary $C$, Let $J$ be the current density - $J=\rho v$, with $\rho$ the density of the current (not time-varying) and $v$ the velocity. The current can be re-expressed as $I = \iint_S J\cdot\hat{n}dA$. (If the current flows through a wire and $S$ is much bigger than the wire, this is still valid as $\rho=0$ outside of the wire.)
|
||||
|
||||
We then have:
|
||||
|
||||
|
||||
$$~
|
||||
```math
|
||||
\mu_0 \iint_S J\cdot\hat{N}dA =
|
||||
\mu_0 I =
|
||||
\oint_C B\cdot\hat{T} ds =
|
||||
\iint_S (\nabla\times{B})\cdot\hat{N}dA.
|
||||
~$$
|
||||
```
|
||||
|
||||
As $S$ and $C$ are arbitrary, this implies the integrands of the surface integrals are equal, or:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla\times{B} = \mu_0 J.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
##### Example: Faraday's law
|
||||
|
||||
(Strang) Suppose $C$ is a wire and there is a time-varying magnetic field $B(t)$. Then Faraday's law says the *flux* passing within $C$ through a surface $S$ with boundary $C$ of the magnetic field, $\phi = \iint B\cdot\hat{N}dS$, induces an electric field $E$ that does work:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\oint_C E\cdot\hat{T}ds = -\frac{\partial{\phi}}{\partial{t}}.
|
||||
~$$
|
||||
```
|
||||
|
||||
Faraday's law is an empirical statement. Stokes' theorem can be used to produce one of Maxwell's equations. For any surface $S$, as above with its boundary being $C$, we have both:
|
||||
|
||||
$$~
|
||||
```math
|
||||
-\iint_S \left(\frac{\partial{B}}{\partial{t}}\cdot\hat{N}\right)dS =
|
||||
-\frac{\partial{\phi}}{\partial{t}} =
|
||||
\oint_C E\cdot\hat{T}ds =
|
||||
\iint_S (\nabla\times{E}) dS.
|
||||
~$$
|
||||
```
|
||||
|
||||
This is true for any capping surface for $C$. Shrinking $C$ to a point means it will hold for each point in $R^3$. That is:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla\times{E} = -\frac{\partial{B}}{\partial{t}}.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
##### Example: Conservative fields
|
||||
@ -783,20 +793,20 @@ curl(F(x,y,z), [x,y,z])
|
||||
|
||||
We need $\phi$ with $\partial{\phi}/\partial{x} = F_x = yz^2$. To that end, we integrate in $x$:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\phi(x,y,z) = \int yz^2 dx = xyz^2 + g(y,z),
|
||||
~$$
|
||||
```
|
||||
the function $g(y,z)$ is a "constant" of integration (it doesn't depend on $x$). That $\partial{\phi}/\partial{x} = F_x$ is true is easy to verify. Now, consider the partial in $y$:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\frac{\partial{\phi}}{\partial{y}} = xz^2 + \frac{\partial{g}}{\partial{y}} = F_y = xz^2.
|
||||
~$$
|
||||
```
|
||||
|
||||
So we have $\frac{\partial{g}}{\partial{y}}=0$ or $g(y,z) = h(z)$, some constant in $y$. Finally, we must have $\partial{\phi}/\partial{z} = F_z$, or
|
||||
|
||||
$$~
|
||||
```math
|
||||
\frac{\partial{\phi}}{\partial{z}} = 2xyz + h'(z) = F_z = 2xyz,
|
||||
~$$
|
||||
```
|
||||
|
||||
So $h'(z) = 0$. This value can be any constant, even $0$ which we take, so that $g(y,z) = 0$ and $\phi(x,y,z) = xyz^2$ is a scalar potential for $F$.
|
||||
|
||||
@ -847,18 +857,18 @@ However, the function $F(x,y,z) = \langle x, y,z\rangle/\sqrt{x^2+y^2+z^2}$ has
|
||||
The divergence theorem is a consequence of a simple observation. Consider two adjacent cubic regions that share a common face.
|
||||
The boundary integral, $\oint_S F\cdot\hat{N} dA$, can be computed for each cube. The surface integral requires a choice of normal, and the convention is to use the outward pointing normal. The common face of the two cubes has *different* outward pointing normals, the difference being a minus sign. As such, the contribution of the surface integral over this face for one cube is *cancelled* out by the contribution of the surface integral over this face for the adjacent cube. As with Green's theorem, this means for a cubic partition, that only the contribution over the boundary is needed to compute the boundary integral. In formulas, if $V$ is a $3$ dimensional cubic region with boundary $S$ and it is partitioned into smaller cubic subregions, $V_i$ with surfaces $S_i$, we have:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\oint_S F\cdot{N} dA = \sum \oint_{S_i} F\cdot{N} dA.
|
||||
~$$
|
||||
```
|
||||
|
||||
If the partition provides a microscopic perspective, then the divergence approximation $\nabla\cdot{F} \approx (1/\Delta{V_i}) \oint_{S_i} F\cdot{N} dA$ can be used to say:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\oint_S F\cdot{N} dA =
|
||||
\sum \oint_{S_i} F\cdot{N} dA \approx
|
||||
\sum (\nabla\cdot{F})\Delta{V_i} \approx
|
||||
\iiint_V \nabla\cdot{F} dV,
|
||||
~$$
|
||||
```
|
||||
|
||||
the last approximation through a Riemann sum approximation. This heuristic leads to:
|
||||
|
||||
@ -965,29 +975,29 @@ The divergence theorem provides two means to compute a value, the point here is
|
||||
|
||||
Following Schey, we now consider a continuous analog to the crowd counting problem through a flow with a non-uniform density that may vary in time. Let $\rho(x,y,z;t)$ be the time-varying density and $v(x,y,z;t)$ be a vector field indicating the direction of flow. Consider some three-dimensional volume, $V$, with boundary $S$ (though two-dimensional would also be applicable). Then these integrals have interpretations:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\begin{align}
|
||||
\iiint_V \rho dV &&\quad\text{Amount contained within }V\\
|
||||
\frac{\partial}{\partial{t}} \iiint_V \rho dV &=
|
||||
\iiint_V \frac{\partial{\rho}}{\partial{t}} dV &\quad\text{Change in time of amount contained within }V
|
||||
\end{align}
|
||||
~$$
|
||||
```
|
||||
|
||||
Moving the derivative inside the integral requires an assumption of continuity.
|
||||
Assume the material is *conserved*, meaning that if the amount in the volume $V$ changes it must flow in and out through the boundary. The flow out through $S$, the boundary of $V$, is
|
||||
|
||||
$$~
|
||||
```math
|
||||
\oint_S (\rho v)\cdot\hat{N} dS,
|
||||
~$$
|
||||
```
|
||||
|
||||
using the customary outward pointing normal for the orientation of $S$.
|
||||
|
||||
So we have:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\iiint_V \frac{\partial{\rho}}{\partial{t}} dV =
|
||||
-\oint_S (\rho v)\cdot\hat{N} dS = - \iiint_V \nabla\cdot\left(\rho v\right)dV.
|
||||
~$$
|
||||
```
|
||||
|
||||
The last equality by the divergence theorem, the minus sign as a positive change in amount within $V$ means flow *opposite* the outward pointing normal for $S$.
|
||||
|
||||
@ -995,9 +1005,9 @@ The volume $V$ was arbitrary. While it isn't the case that two integrals being e
|
||||
|
||||
That is, under the *assumptions* that material is conserved and density is continuous a continuity equation can be derived from the divergence theorem:
|
||||
|
||||
$$~
|
||||
```math
|
||||
\nabla\cdot(\rho v) = - \frac{\partial{\rho}}{dt}.
|
||||
~$$
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -1018,11 +1028,11 @@ The simplification done by SymPy masks the presence of $R^{-5/2}$ when taking th
|
||||
|
||||
*Were* the divergence theorem applicable, then the integral of $F$ over the unit sphere would mean:
|
||||
|
||||
$$~
|
||||
```math
|
||||
0 = \iiint_V \nabla\cdot{F} dV =
|
||||
\oint_S F\cdot{N}dS = \oint_S \frac{R}{\|R\|^3} \cdot{R} dS =
|
||||
\oint_S 1 dS = 4\pi.
|
||||
~$$
|
||||
```
|
||||
|
||||
Clearly, as $0$ is not equal to $4\pi$, the divergence theorem can not apply.
|
||||
|
||||
@ -1045,8 +1055,8 @@ L"We must have $\text{curl}(F) = 1$",
|
||||
L"We must have $\text{curl}(F) = 0$",
|
||||
L"We must have $\text{curl}(F) = x$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1074,8 +1084,8 @@ raw" ``(1/2) \int r d\theta``",
|
||||
raw" ``\int r^2 d\theta``",
|
||||
raw" ``(1/2) \int r^2d\theta``"
|
||||
]
|
||||
ans=4
|
||||
radioq(choices, ans)
|
||||
answ=4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1094,8 +1104,8 @@ raw" ``3\pi/8``",
|
||||
raw" ``\pi/4``",
|
||||
raw" ``\pi/2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1110,8 +1120,8 @@ raw" ``0``",
|
||||
raw" ``1``",
|
||||
raw" ``2``"
|
||||
]
|
||||
ans =1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ =1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
As the curl is a constant, say $c$, we have $\iint_S (\nabla\times{F}) dS = c \cdot 1$. This is?
|
||||
@ -1122,8 +1132,8 @@ raw" ``0``",
|
||||
raw" ``1``",
|
||||
raw" ``2``"
|
||||
]
|
||||
ans =1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ =1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
To integrate around the boundary we have ``4`` terms: the path $A$ connecting $(0,0)$ to $(1,0)$ (on the $x$ axis), the path $B$ connecting $(1,0)$ to $(1,1)$, the path $C$ connecting $(1,1)$ to $(0,1)$, and the path $D$ connecting $(0,1)$ to $(0,0)$ (along the $y$ axis).
|
||||
@ -1132,8 +1142,8 @@ Which path has tangent $\hat{j}$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["`` A``","`` B``"," ``C``"," ``D``"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
Along path $C$, $F(x,y) = [1,x]$ and $\hat{T}=-\hat{i}$ so $F\cdot\hat{T} = -1$. The path integral $\int_C (F\cdot\hat{T})ds = -1$. What is the value of the path integral over $A$?
|
||||
@ -1144,8 +1154,8 @@ raw" ``-1``",
|
||||
raw" ``0``",
|
||||
raw" ``1``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
What is the integral over the oriented boundary of $S$?
|
||||
@ -1156,8 +1166,8 @@ raw" ``0``",
|
||||
raw" ``1``",
|
||||
raw" ``2``"
|
||||
]
|
||||
ans =1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ =1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1171,8 +1181,8 @@ choices = [
|
||||
L"They are the same, as Green's theorem applies to the area, $S$, between $C_1$ and $C_2$ so $\iint_S \nabla\cdot{F}dA = 0$."
|
||||
L"They differ by a minus sign, as Green's theorem applies to the area, $S$, between $C_1$ and $C_2$ so $\iint_S \nabla\cdot{F}dA = 0$."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1185,8 +1195,8 @@ choices = [
|
||||
L"Also $2\pi$, as Green's theorem applies to the region formed by the square minus the circle and so the overall flow integral around the boundary is $0$, so the two will be the same.",
|
||||
L"It is $-2\pi$, as Green's theorem applies to the region formed by the square minus the circle and so the overall flow integral around the boundary is $0$, so the two will have opposite signs, but the same magnitude."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1199,8 +1209,8 @@ raw" ``4/3 \pi``",
|
||||
raw" ``4\pi``",
|
||||
raw" ``\pi``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1214,8 +1224,8 @@ raw" ``1``",
|
||||
raw" ``2``",
|
||||
raw" ``3``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1229,8 +1239,8 @@ raw" ``\log(\rho)``",
|
||||
raw" ``1/\rho``",
|
||||
raw" ``\rho``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Based on this information, for $S$ a surface not including the origin with boundary $C$, a simple closed curve, what is $\oint_C F\cdot\hat{T}ds$?
|
||||
@ -1240,8 +1250,8 @@ choices = [
|
||||
L"It is $0$, as, by Stoke's theorem, it is equivalent to $\iint_S (\nabla\times\nabla{\phi})dS = \iint_S 0 dS = 0$.",
|
||||
L"It is $2\pi$, as this is the circumference of the unit circle"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1254,8 +1264,8 @@ raw" ``2\pi``",
|
||||
raw" ``2``",
|
||||
raw" ``0``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1274,8 +1284,8 @@ choices = [
|
||||
"the field is *not* conservative.",
|
||||
"the field *is* conservative"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1311,8 +1321,8 @@ choices = [
|
||||
"The maximum number in a row",
|
||||
"The row number plus 1"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1321,10 +1331,10 @@ radioq(choices, ans)
|
||||
|
||||
In 1846, Cauchy proved
|
||||
|
||||
$$~
|
||||
```math
|
||||
\int\left(p\frac{dx}{ds} + q \frac{dy}{ds}\right)ds =
|
||||
\pm\iint\left(\frac{\partial{p}}{\partial{y}} - \frac{\partial{q}}{\partial{x}}\right)dx dy.
|
||||
~$$
|
||||
```
|
||||
|
||||
This is a form of:
|
||||
|
||||
@ -1334,6 +1344,6 @@ choices = [
|
||||
"The divergence (Gauss') theorem",
|
||||
"Stokes' theorem"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
@ -13,12 +13,12 @@ using Roots
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
const frontmatter = (
|
||||
title = "Arc length",
|
||||
description = "Calculus with Julia: Arc length",
|
||||
tags = ["CalculusWithJulia", "integrals", "arc length"],
|
||||
frontmatter = (
|
||||
title = "Arc length",
|
||||
description = "Calculus with Julia: Arc length",
|
||||
tags = ["CalculusWithJulia", "integrals", "arc length"],
|
||||
);
|
||||
fig_size=(600, 400)
|
||||
fig_size=(800, 600)
|
||||
|
||||
nothing
|
||||
```
|
||||
@ -57,20 +57,15 @@ f'(t)^2}$ is Riemann integrable.
|
||||
> For the special case of the graph of a function $f(x)$ between $a$ and $b$ the formula becomes $L = \int_a^b \sqrt{ 1 + f'(x)^2} dx$ (taking $g(t) = t$).
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
|
||||
The form of the integral may seem daunting with the square root and
|
||||
the derivatives. A more general writing would create a vector out of
|
||||
the two functions: $\phi(t) = \langle g(t), f(t) \rangle$. It is
|
||||
natural to then let $\phi'(t) = \langle g'(t), f'(t) \rangle$. With
|
||||
this, the integrand is just the norm - or length - of the
|
||||
derivative, or $L=\int \| \phi'(t) \| dt$. This is similar to the
|
||||
distance traveled being the integral of the speed, or the absolute
|
||||
value of the derivative of position.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The form of the integral may seem daunting with the square root and
|
||||
the derivatives. A more general writing would create a vector out of
|
||||
the two functions: $\phi(t) = \langle g(t), f(t) \rangle$. It is
|
||||
natural to then let $\phi'(t) = \langle g'(t), f'(t) \rangle$. With
|
||||
this, the integrand is just the norm - or length - of the
|
||||
derivative, or $L=\int \| \phi'(t) \| dt$. This is similar to the
|
||||
distance traveled being the integral of the speed, or the absolute
|
||||
value of the derivative of position.
|
||||
|
||||
|
||||
To see why, any partition of the interval $[a,b]$ by $a = t_0 < t_1 < \cdots < t_n =b$ gives rise to $n+1$ points in the plane given by $(g(t_i), f(t_i))$.
|
||||
@ -154,25 +149,20 @@ L = \int_a^b \sqrt{f'(t)^2 + g'(t)^2} dt.
|
||||
(This needs a technical adjustment to the Riemann theorem, as we are evaluating our function at two points in the interval. A general proof is [here](https://randomproofs.files.wordpress.com/2010/11/arc_length.pdf).)
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
!!! note
|
||||
[Bressoud](http://www.math.harvard.edu/~knill/teaching/math1a_2011/exhibits/bressoud/)
|
||||
notes that Gregory (1668) proved this formula for arc length of the
|
||||
graph of a function by showing that the length of the curve $f(x)$ is defined
|
||||
by the area under $\sqrt{1 + f'(x)^2}$. (It is commented that this was
|
||||
also known a bit earlier by von Heurat.) Gregory went further though,
|
||||
as part of the fundamental theorem of calculus was contained in his
|
||||
work. Gregory then posed this inverse question: given a curve
|
||||
$y=g(x)$ find a function $u(x)$ so that the area under $g$ is equal to
|
||||
the length of the second curve. The answer given was $u(x) =
|
||||
(1/c)\int_a^x \sqrt{g^2(t) - c^2}$, which if $g(t) = \sqrt{1 + f'(t)^2}$
|
||||
and $c=1$ says $u(x) = \int_a^x f(t)dt$.
|
||||
|
||||
[Bressoud](http://www.math.harvard.edu/~knill/teaching/math1a_2011/exhibits/bressoud/)
|
||||
notes that Gregory (1668) proved this formula for arc length of the
|
||||
graph of a function by showing that the length of the curve $f(x)$ is defined
|
||||
by the area under $\sqrt{1 + f'(x)^2}$. (It is commented that this was
|
||||
also known a bit earlier by von Heurat.) Gregory went further though,
|
||||
as part of the fundamental theorem of calculus was contained in his
|
||||
work. Gregory then posed this inverse question: given a curve
|
||||
$y=g(x)$ find a function $u(x)$ so that the area under $g$ is equal to
|
||||
the length of the second curve. The answer given was $u(x) =
|
||||
(1/c)\int_a^x \sqrt{g^2(t) - c^2}$, which if $g(t) = \sqrt{1 + f'(t)^2}$
|
||||
and $c=1$ says $u(x) = \int_a^x f(t)dt$.
|
||||
|
||||
An analogy might be a sausage maker. These take a mass of ground-up sausage material and return a long length of sausage. The material going in would depend on time via an equation like $\int_0^t g(u) du$ and the length coming out would be a constant (accounting for the cross section) times $u(t) = \int_0^t \sqrt{1 + g'(s)} ds$.
|
||||
|
||||
""")
|
||||
```
|
||||
An analogy might be a sausage maker. These take a mass of ground-up sausage material and return a long length of sausage. The material going in would depend on time via an equation like $\int_0^t g(u) du$ and the length coming out would be a constant (accounting for the cross section) times $u(t) = \int_0^t \sqrt{1 + g'(s)} ds$.
|
||||
|
||||
#### Examples
|
||||
|
||||
@ -194,13 +184,8 @@ f(x) = x^2
|
||||
plot(f, 0, 1)
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
|
||||
The integrand $\sqrt{1 + f'(x)^2}$ may seem odd at first, but it can be interpreted as the length of the hypotenuse of a right triangle with "run" of $1$ and "rise" of $f'(x)$. This triangle is easily formed using the tangent line to the graph of $f(x)$. By multiplying by $dx$, the integral is "summing" up the lengths of infinitesimal pieces of the tangent line approximation.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The integrand $\sqrt{1 + f'(x)^2}$ may seem odd at first, but it can be interpreted as the length of the hypotenuse of a right triangle with "run" of $1$ and "rise" of $f'(x)$. This triangle is easily formed using the tangent line to the graph of $f(x)$. By multiplying by $dx$, the integral is "summing" up the lengths of infinitesimal pieces of the tangent line approximation.
|
||||
|
||||
|
||||
##### Example
|
||||
@ -705,8 +690,8 @@ f(x) = \left(\frac{g}{k v_0\cos(\theta)} + \tan(\theta) \right) x + \frac{g}{k^2
|
||||
This comes from solving the projectile motion equations with a drag force *proportional* to the velocity. This function satisfies:
|
||||
|
||||
```julia; hold=true
|
||||
@syms g::postive, k::postive, v₀::positive, θ::postive, x::postive
|
||||
ex = (g/(k*v₀*cos(θ)) + tan(θ))*x + g/k^2 * log(1 - k/(v₀*cos(θ))*x)
|
||||
@syms gₑ::postive, k::postive, v₀::positive, θ::postive, x::postive
|
||||
ex = (gₑ/(k*v₀*cos(θ)) + tan(θ))*x + gₑ/k^2 * log(1 - k/(v₀*cos(θ))*x)
|
||||
diff(ex, x, x), diff(ex, x, x, x,)
|
||||
```
|
||||
|
||||
@ -857,16 +842,16 @@ y = a \ln\frac{a + \sqrt{a^2 - x^2}}{x} - \sqrt{a^2 - x^2}
|
||||
This can be entered into `julia` as:
|
||||
|
||||
```julia;
|
||||
g(x, a) = a * log((a + sqrt(a^2 - x^2))/x) - sqrt(a^2 - x^2)
|
||||
h(x, a) = a * log((a + sqrt(a^2 - x^2))/x) - sqrt(a^2 - x^2)
|
||||
```
|
||||
|
||||
|
||||
Let $a=12$, $f(x) = g(x, a)$. Compute the length the bow of the
|
||||
Let $a=12$, $f(x) = h(x, a)$. Compute the length the bow of the
|
||||
boat has traveled between $x=1$ and $x=a$ using `quadgk`.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
a = 12
|
||||
f(x) = g(x, a);
|
||||
f(x) = h(x, a);
|
||||
val = quadgk(x -> sqrt(1 + D(f)(x)^2), 1, a)[1];
|
||||
numericq(val, 1e-3)
|
||||
```
|
||||
@ -874,13 +859,8 @@ numericq(val, 1e-3)
|
||||
(The most elementary description of this curve is in terms
|
||||
of the relationship $dy/dx = -\sqrt{a^2-x^2}/x$ which could be used in place of `D(f)` in your work.)
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
note("""
|
||||
|
||||
To see an example of how the tractrix can be found in an everyday observation, follow this link on a description of [bicycle](https://simonsfoundation.org/multimedia/mathematical-impressions-bicycle-tracks) tracks.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
To see an example of how the tractrix can be found in an everyday observation, follow this link on a description of [bicycle](https://simonsfoundation.org/multimedia/mathematical-impressions-bicycle-tracks) tracks.
|
||||
|
||||
###### Question
|
||||
|
||||
@ -905,12 +885,14 @@ radioq(choices, 1)
|
||||
|
||||
A curve is parameterized by $g(t) = t + \sin(t)$ and $f(t) = \cos(t)$. Find the arc length of the curve between $t=0$ and $\pi$.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
g(t) = t + sin(t)
|
||||
f(t) = cos(t)
|
||||
a, b = 0, pi
|
||||
val, _ = quadgk( x -> sqrt(D(g)(x)^2 + D(f)(x)^2), a, b)
|
||||
numericq(val)
|
||||
```julia; echo=false
|
||||
let
|
||||
g(t) = t + sin(t)
|
||||
f(t) = cos(t)
|
||||
a, b = 0, pi
|
||||
val, _ = quadgk( x -> sqrt(D(g)(x)^2 + D(f)(x)^2), a, b)
|
||||
numericq(val)
|
||||
end
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -918,24 +900,28 @@ numericq(val)
|
||||
The [astroid](http://www-history.mcs.st-and.ac.uk/Curves/Astroid.html) is
|
||||
a curve parameterized by $g(t) = \cos(t)^3$ and $f(t) = \sin(t)^3$. Find the arc length of the curve between $t=0$ and $2\pi$. (This can be computed by hand or numerically.)
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
g(t) = cos(t)^3
|
||||
f(t) = sin(t)^3
|
||||
a, b = 0, 2pi
|
||||
val, _ = quadgk( x -> sqrt(D(g)(x)^2 + D(f)(x)^2), a, b)
|
||||
numericq(val)
|
||||
```julia; echo=false
|
||||
let
|
||||
g(t) = cos(t)^3
|
||||
f(t) = sin(t)^3
|
||||
a, b = 0, 2pi
|
||||
val, _ = quadgk( x -> sqrt(D(g)(x)^2 + D(f)(x)^2), a, b)
|
||||
numericq(val)
|
||||
end
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
A curve is parameterized by $g(t) = (2t + 3)^{2/3}/3$ and $f(t) = t + t^2/2$, for $0\leq t \leq 3$. Compute the arc-length numerically or by hand:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
g(t) = (2t+3)^(2/3)/3
|
||||
f(t) = t + t^2/2
|
||||
a, b = 0, 3
|
||||
val, _ = quadgk( x -> sqrt(D(g)(x)^2 + D(f)(x)^2), a, b)
|
||||
numericq(val)
|
||||
```julia; echo=false
|
||||
let
|
||||
g(t) = (2t+3)^(2/3)/3
|
||||
f(t) = t + t^2/2
|
||||
a, b = 0, 3
|
||||
val, _ = quadgk( x -> sqrt(D(g)(x)^2 + D(f)(x)^2), a, b)
|
||||
numericq(val)
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
@ -944,12 +930,14 @@ numericq(val)
|
||||
The cycloid is parameterized by $g(t) = a(t - \sin(t))$ and $f(t) = a(1 - \cos(t))$ for $a > 0$. Taking $a=3$, and $t$ in $[0, 2\pi]$, find the length of the curve traced out. (This was solved by the architect and polymath [Wren](https://www.maa.org/sites/default/files/pdf/cmj_ftp/CMJ/January%202010/3%20Articles/3%20Martin/08-170.pdf) in 1650.)
|
||||
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
a = 3
|
||||
g(t) = a*(t - sin(t))
|
||||
f(t) = a*(1 - cos(t))
|
||||
val, _ = quadgk( x -> sqrt(D(g)(x)^2 + D(f)(x)^2), 0, 2pi)
|
||||
numericq(val)
|
||||
```julia; echo=false
|
||||
let
|
||||
a = 3
|
||||
g(t) = a*(t - sin(t))
|
||||
f(t) = a*(1 - cos(t))
|
||||
val, _ = quadgk( x -> sqrt(D(g)(x)^2 + D(f)(x)^2), 0, 2pi)
|
||||
numericq(val)
|
||||
end
|
||||
```
|
||||
|
||||
A cycloid parameterized this way can be generated by a circle of radius ``a``. Based on this example, what do you think Wren wrote to Pascal about this length:
|
||||
@ -964,20 +952,16 @@ circle."]
|
||||
radioq(choices, 3, keep_order=true)
|
||||
```
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
note("""
|
||||
In [Martin](https://www.maa.org/sites/default/files/pdf/cmj_ftp/CMJ/January%202010/3%20Articles/3%20Martin/08-170.pdf) we read why Wren was mailing Pascal:
|
||||
!!! note
|
||||
In [Martin](https://www.maa.org/sites/default/files/pdf/cmj_ftp/CMJ/January%202010/3%20Articles/3%20Martin/08-170.pdf) we read why Wren was mailing Pascal:
|
||||
|
||||
After demonstrating mathematical talent at an early age, Blaise Pascal
|
||||
turned his attention to theology, denouncing the study of mathematics
|
||||
as a vainglorious pursuit. Then one night, unable to sleep as the
|
||||
result of a toothache, he began thinking about the cycloid and to his
|
||||
surprise, his tooth stopped aching. Taking this as a sign that he had
|
||||
God’s approval to continue, Pascal spent the next eight days studying
|
||||
the curve. During this time he discovered nearly all of the geometric
|
||||
properties of the cycloid. He issued some of his results in ``1658`` in
|
||||
the form of a contest, offering a prize of forty Spanish gold pieces
|
||||
and a second prize of twenty pieces.
|
||||
|
||||
""")
|
||||
```
|
||||
After demonstrating mathematical talent at an early age, Blaise Pascal
|
||||
turned his attention to theology, denouncing the study of mathematics
|
||||
as a vainglorious pursuit. Then one night, unable to sleep as the
|
||||
result of a toothache, he began thinking about the cycloid and to his
|
||||
surprise, his tooth stopped aching. Taking this as a sign that he had
|
||||
God’s approval to continue, Pascal spent the next eight days studying
|
||||
the curve. During this time he discovered nearly all of the geometric
|
||||
properties of the cycloid. He issued some of his results in ``1658`` in
|
||||
the form of a contest, offering a prize of forty Spanish gold pieces
|
||||
and a second prize of twenty pieces.
|
||||
|
||||
@ -14,7 +14,7 @@ using Roots
|
||||
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
fig_size = (600, 400)
|
||||
fig_size = (800, 600)
|
||||
using Markdown, Mustache
|
||||
|
||||
const frontmatter = (
|
||||
@ -284,17 +284,13 @@ first $n$ natural numbers.
|
||||
|
||||
With this expression, it is readily seen that as $n$ gets large this value gets close to $2/6 = 1/3$.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
!!! note
|
||||
The above approach, like Archimedes', ends with a limit being
|
||||
taken. The answer comes from using a limit to add a big number of
|
||||
small values. As with all limit questions, worrying about whether a
|
||||
limit exists is fundamental. For this problem, we will see that for
|
||||
the general statement there is a stretching of the formal concept of a limit.
|
||||
|
||||
The above approach, like Archimedes', ends with a limit being
|
||||
taken. The answer comes from using a limit to add a big number of
|
||||
small values. As with all limit questions, worrying about whether a
|
||||
limit exists is fundamental. For this problem, we will see that for
|
||||
the general statement there is a stretching of the formal concept of a limit.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
@ -897,17 +893,12 @@ derivative over $[a,b]$. This is significant, the error in $10$ steps
|
||||
of Simpson's rule is on the scale of the error of $10,000$ steps of
|
||||
the Riemann sum for well-behaved functions.
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
|
||||
The Wikipedia article mentions that Kepler used a similar formula $100$
|
||||
years prior to Simpson, or about $200$ years before Riemann published
|
||||
his work. Again, the value in Riemann's work is not the computation of
|
||||
the answer, but the framework it provides in determining if a function
|
||||
is Riemann integrable or not.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The Wikipedia article mentions that Kepler used a similar formula $100$
|
||||
years prior to Simpson, or about $200$ years before Riemann published
|
||||
his work. Again, the value in Riemann's work is not the computation of
|
||||
the answer, but the framework it provides in determining if a function
|
||||
is Riemann integrable or not.
|
||||
|
||||
## Gauss quadrature
|
||||
|
||||
@ -1289,8 +1280,8 @@ choices = [
|
||||
"``p``",
|
||||
"``1-p``",
|
||||
"``p^2``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1303,8 +1294,8 @@ choices = [
|
||||
"``2^5/5 - 0^5/5``",
|
||||
"``2^4/4 - 0^4/4``",
|
||||
"``3\\cdot 2^3 - 3 \\cdot 0^3``"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1344,8 +1335,8 @@ L"The area between $c$ and $b$ must be positive, so $F(c) < F(b)$.",
|
||||
"``F(b) - F(c) = F(a).``",
|
||||
L" $F(x)$ is continuous, so between $a$ and $b$ has an extreme value, which must be at $c$. So $F(c) \geq F(b)$."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1359,8 +1350,8 @@ choices = [
|
||||
"``10/100``",
|
||||
"``(10 - 0) \\cdot e^{10} / 100^4``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1440,9 +1431,11 @@ The area under a curve approximated by a Riemann sum.
|
||||
#CalculusWithJulia.WeaveSupport.JSXGraph(:integrals, url, caption)
|
||||
# This is just wrong...
|
||||
url = "https://raw.githubusercontent.com/jverzani/CalculusWithJulia.jl/master/CwJ/integrals/riemann.js"
|
||||
url = "./riemann.js"
|
||||
CalculusWithJulia.WeaveSupport.JSXGraph(url, caption)
|
||||
```
|
||||
|
||||
|
||||
The interactive graphic shows the area of a right-Riemann sum for different partitions. The function is
|
||||
|
||||
```math
|
||||
@ -1502,8 +1495,8 @@ L"around $10^{-2}$",
|
||||
L"around $10^{-4}$",
|
||||
L"around $10^{-6}$",
|
||||
L"around $10^{-8}$"]
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
@ -317,13 +317,9 @@ g1(y)=exp(y)-1 # y=log(x+1) so e^y = x + 1, x = e^y - 1
|
||||
quadgk(y -> f1(y) - g1(y), a1, b1)[1]
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
!!! note
|
||||
When doing problems by hand this latter style can often reduce the complications, but when approaching the task numerically, the first two styles are generally easier, though computationally more expensive.
|
||||
|
||||
When doing problems by hand this latter style can often reduce the complications, but when approaching the task numerically, the first two styles are generally easier, though computationally more expensive.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
#### Integrating in different directions
|
||||
|
||||
@ -427,7 +423,7 @@ Find the area enclosed by the curves $y=2-x^2$ and $y=x^2 - 3$.
|
||||
```julia; hold=true; echo=false
|
||||
f(x) = 2 - x^2
|
||||
g(x) = x^2 - 3
|
||||
a,b = find_zeros(x -> f(x) - g(x), -10,10)
|
||||
a,b = find_zeros(x -> f(x) - g(x), -10, 10)
|
||||
val, _ = quadgk(x -> f(x) - g(x), a, b)
|
||||
numericq(val)
|
||||
```
|
||||
@ -569,16 +565,12 @@ Is the guess that the entire sculpture is more than two tons?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices=["Less than two tons", "More than two tons"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
```
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
note("""
|
||||
We used area to estimate weight in this example, but Galileo used weight to estimate area. It is [mentioned](https://www.maa.org/sites/default/files/pdf/cmj_ftp/CMJ/January%202010/3%20Articles/3%20Martin/08-170.pdf) by Martin that in order to estimate the area enclosed by one arch of a cycloid, Galileo cut the arch from from some material and compared the weight to the weight of the generating circle. He concluded the area is close to ``3`` times that of the circle, a conjecture proved by Roberval in 1634.
|
||||
""")
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
!!! note
|
||||
We used area to estimate weight in this example, but Galileo used weight to estimate area. It is [mentioned](https://www.maa.org/sites/default/files/pdf/cmj_ftp/CMJ/January%202010/3%20Articles/3%20Martin/08-170.pdf) by Martin that in order to estimate the area enclosed by one arch of a cycloid, Galileo cut the arch from from some material and compared the weight to the weight of the generating circle. He concluded the area is close to ``3`` times that of the circle, a conjecture proved by Roberval in 1634.
|
||||
|
||||
|
||||
###### Question
|
||||
|
||||
@ -192,13 +192,9 @@ cm = top / bottom
|
||||
|
||||
Our guess from the diagram proves correct.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
!!! note
|
||||
It proves convenient to use the `->` notation for an anonymous function above, as our function `h` is not what is being integrated all the time, but some simple modification. If this isn't palatable, a new function could be defined and passed along to `quadgk`.
|
||||
|
||||
It proves convenient to use the `->` notation for an anonymous function above, as our function `h` is not what is being integrated all the time, but some simple modification. If this isn't palatable, a new function could be defined and passed along to `quadgk`.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
@ -220,13 +216,9 @@ For fun, we compare this to the median, which is the value $M$ so that the total
|
||||
|
||||
Solving $1/2 = 1 - e^{-M}$ gives $M=\log(2) = 0.69...$, The median is to the left of the mean in this example.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
!!! note
|
||||
In this example, we used an infinite region, so the idea of "balancing" may be a bit unrealistic, nonetheless, this intuitive interpretation is still a good one to keep this in mind. The point of comparing to the median is that the balancing point is to the right of where the area splits in half. Basically, the center of mass follows in the direction of the area far to the right of the median, as this area is skewed in that direction.
|
||||
|
||||
In this example, we used an infinite region, so the idea of "balancing" may be a bit unrealistic, nonetheless, this intuitive interpretation is still a good one to keep this in mind. The point of comparing to the median is that the balancing point is to the right of where the area splits in half. Basically, the center of mass follows in the direction of the area far to the right of the median, as this area is skewed in that direction.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
@ -308,13 +300,9 @@ integrate(x*fx, (x, 0, b)) / integrate(fx, (x, 0, b))
|
||||
|
||||
But really, we should have just noted that simply by switching the labels $a$ and $b$ in the diagram we could have discovered this formula.
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
!!! note
|
||||
The [centroid](http://en.wikipedia.org/wiki/Centroid) of a region in the plane is just $(\text{cm}_x, \text{cm}_y)$. This last fact says the centroid of the right triangle is just $(b/3, a/3)$. The centroid can be found by other geometric means. The link shows the plumb line method. For triangles, the centroid is also the intersection point of the medians, the lines that connect a vertex with its opposite midpoint.
|
||||
|
||||
The [centroid](http://en.wikipedia.org/wiki/Centroid) of a region in the plane is just $(\text{cm}_x, \text{cm}_y)$. This last fact says the centroid of the right triangle is just $(b/3, a/3)$. The centroid can be found by other geometric means. The link shows the plumb line method. For triangles, the centroid is also the intersection point of the medians, the lines that connect a vertex with its opposite midpoint.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ const frontmatter = (
|
||||
description = "Calculus with Julia: Fundamental Theorem or Calculus",
|
||||
tags = ["CalculusWithJulia", "integrals", "fundamental theorem or calculus"],
|
||||
);
|
||||
fig_size = (600, 400)
|
||||
fig_size = (800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
@ -107,11 +107,15 @@ definite integral and the derivative we have
|
||||
```math
|
||||
\begin{align*}
|
||||
F'(x) = & \frac{d}{dx} \int_a^x f(u) du \\
|
||||
& \approx \frac{F(x) - F(x-h)}{h} = \frac{\int_a^x f(u) du - \int_a^{x-h} f(u) du}{h}\\
|
||||
& \approx \frac{\left(f(a + 1h)h + f(a + 2h)h + \cdots + f(a + (M-1)h)h + f(a + Mh)h\right)}{h} -
|
||||
& \approx \frac{F(x) - F(x-h)}{h} \\
|
||||
&= \frac{\int_a^x f(u) du - \int_a^{x-h} f(u) du}{h}\\
|
||||
& \approx \frac{\left(f(a + 1h)h + f(a + 2h)h + \cdots + f(a + (M-1)h)h + f(a + Mh)h\right)}{h}\\
|
||||
&- \quad
|
||||
\frac{\left(f(a + 1h)h + f(a + 2h)h + \cdots + f(a + (M-1)h)h \right)}{h} \\
|
||||
& = \left(f(a + 1h) + f(a + 2h) + \cdots + f(a + (M-1)h) + f(a + Mh)\right) -
|
||||
\left(f(a + 1h) + f(a + 2h) + \cdots + f(a + (M-1)h) \right)
|
||||
& = \left(f(a + 1h) + \quad f(a + 2h) + \cdots + f(a + (M-1)h) + f(a + Mh)\right)\\
|
||||
&- \quad
|
||||
\left(f(a + 1h) + f(a + 2h) + \cdots + f(a + (M-1)h) \right) \\
|
||||
&= f(a + Mh).
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
@ -152,20 +156,15 @@ With these heuristics, we now have:
|
||||
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
|
||||
In Part 1, the integral $F(x) = \int_a^x f(u) du$ is defined for any
|
||||
Riemann integrable function, $f$. If the function is not continuous,
|
||||
then it is true the $F$ will be continuous, but it need not be true
|
||||
that it is differentiable at all points in $(a,b)$. Forming $F$ from
|
||||
$f$ is a form of *smoothing*. It makes a continuous function out of an
|
||||
integrable one, a differentiable function from a continuous one, and a
|
||||
$k+1$-times differentiable function from a $k$-times differentiable
|
||||
one.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
In Part 1, the integral $F(x) = \int_a^x f(u) du$ is defined for any
|
||||
Riemann integrable function, $f$. If the function is not continuous,
|
||||
then it is true the $F$ will be continuous, but it need not be true
|
||||
that it is differentiable at all points in $(a,b)$. Forming $F$ from
|
||||
$f$ is a form of *smoothing*. It makes a continuous function out of an
|
||||
integrable one, a differentiable function from a continuous one, and a
|
||||
$k+1$-times differentiable function from a $k$-times differentiable
|
||||
one.
|
||||
|
||||
## Using the fundamental theorem of calculus to evaluate definite integrals
|
||||
|
||||
@ -616,7 +615,7 @@ We need to figure out when this is $0$. For that, we use some numeric math.
|
||||
```julia;
|
||||
F(x) = exp(-x^2) * quadgk(t -> exp(t^2), 0, x)[1]
|
||||
Fp(x) = -2x*F(x) + 1
|
||||
cps = find_zeros(Fp, -4,4)
|
||||
cps = find_zeros(Fp, -4, 4)
|
||||
```
|
||||
|
||||
We could take a second derivative to characterize. For that we use
|
||||
@ -714,14 +713,8 @@ dx``, using linearity, as ``\int_0^{x_0} f(x) dx +
|
||||
\int_{x_{n-1}}^{x_n}f(x)dx``. Then all but the last term could be
|
||||
stored from the previous steps of Newton's method. The last term presumably being less costly as it would typically involve a small interval.
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
The trick using a closure relies on an internal way of accessing elements in a closure. The same trick could be implemented many different ways which aren't reliant on undocumented internals, this approach was just a tad more convenient. It shouldn't be copied for work intended for distribution, as the internals may change without notice or deprecation.
|
||||
""")
|
||||
```
|
||||
|
||||
|
||||
|
||||
!!! note
|
||||
The trick using a closure relies on an internal way of accessing elements in a closure. The same trick could be implemented many different ways which aren't reliant on undocumented internals, this approach was just a tad more convenient. It shouldn't be copied for work intended for distribution, as the internals may change without notice or deprecation.
|
||||
|
||||
|
||||
##### Example
|
||||
@ -898,8 +891,8 @@ choices = [
|
||||
"``-x^2\\cos(x) + 2x\\sin(x)``",
|
||||
"``-x^2\\cos(x) + 2x\\sin(x) + 2\\cos(x)``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -914,8 +907,8 @@ choices = [
|
||||
"``-(1+x) e^{-x}``",
|
||||
"``-(1 + x + x^2) e^{-x}``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -978,8 +971,8 @@ choices = [
|
||||
L"Between $0$ and $1$",
|
||||
L"Between $1$ and $5$"
|
||||
]
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
* The position of the particle is $0$ at $t=0$ and:
|
||||
@ -990,8 +983,8 @@ choices = [
|
||||
"``t=2``",
|
||||
"``t=3``",
|
||||
"``t=4``"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
* The position of the particle at time $t=5$ is?
|
||||
@ -1010,8 +1003,8 @@ L"The position, $x(t)$, increases with a slope of $1$",
|
||||
L"The position, $x(t)$, increases quadratically from $-1/2$ to $1$",
|
||||
L"The position, $x(t)$, increases quadratically from $0$ to $1$"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1024,8 +1017,8 @@ choices = [
|
||||
"``-f(t-10)``",
|
||||
"``f(t) - f(t-10)``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1037,8 +1030,8 @@ choices = [
|
||||
"At a critical point",
|
||||
L"At the endpoint $0$",
|
||||
L"At the endpoint $1$"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1058,8 +1051,8 @@ choices = [
|
||||
"The derivative of ``F`` is ``f``, so by the second derivative test, ``x=7``",
|
||||
"The graph of ``f`` has relative maxima at ``x=2,6,8``"
|
||||
]
|
||||
answer = 2
|
||||
radioq(choices, answer)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1073,8 +1066,8 @@ L"At a critical point, either $0$ or $1$",
|
||||
L"At a critical point, $1/2$",
|
||||
L"At the endpoint $0$",
|
||||
L"At the endpoint $1$"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1122,8 +1115,8 @@ choices = [
|
||||
"``A(x) / \\lvert Tx \\rvert = A'(x)``",
|
||||
"``A(x) \\cdot A'(x) = f(x)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
The fact that $\lvert PT \rvert$ is tangent says what in terms of $f(x)$, $A(x)$ and $A'(x)$?
|
||||
@ -1135,8 +1128,8 @@ choices = [
|
||||
"``A(x) / \\lvert Tx \\rvert = A'(x)``",
|
||||
"``A(x) \\cdot A'(x) = f(x)``"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
Solving, we get:
|
||||
@ -1148,8 +1141,8 @@ choices = [
|
||||
"``A'(x) = A(x)``",
|
||||
"``A(x) = f(x)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1160,20 +1153,20 @@ According to [Bressoud](http://www.math.harvard.edu/~knill/teaching/math1a_2011/
|
||||
choices = [
|
||||
L"Part 1: $[\int_a^x f(u) du]' = f$",
|
||||
L"Part 2: $\int_a^b f(u) du = F(b)- F(a)$."]
|
||||
ans=1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ=1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
## More on SymPy's `integrate`
|
||||
|
||||
Finding the value of a definite integral through the fundamental theorem of calculus relies on the algebraic identification of an antiderivative. This is difficult to do by hand and by computer, and is complicated by the fact that not every [elementary ](https://en.wikipedia.org/wiki/Elementary_function)function has an elementary antiderivative.
|
||||
`SymPy`'s documentation on integration indicates that several different means to integrate a function are used internally. As it is of interest here, it is copied with just minor edits below:
|
||||
`SymPy`'s documentation on integration indicates that several different means to integrate a function are used internally. As it is of interest here, it is copied with just minor edits below (from an older version of SymPy):
|
||||
|
||||
|
||||
#### Simple heuristics (based on pattern matching and integral table):
|
||||
|
||||
* most frequently used functions (e.g. polynomials, products of trigonemetric functions)
|
||||
* most frequently used functions (e.g. polynomials, products of trigonometric functions)
|
||||
|
||||
#### Integration of rational functions:
|
||||
|
||||
@ -1250,4 +1243,4 @@ Finding the value of a definite integral through the fundamental theorem of calc
|
||||
is to implement enough of the Risch and Meijer G-function methods
|
||||
so that this can be deleted.
|
||||
Setting `heurisch=true` will cause `integrate` to use only this
|
||||
method. Set `heurisch=false to not use it.
|
||||
method. Set `heurisch=false` to not use it.
|
||||
|
||||
@ -17,7 +17,7 @@ const frontmatter = (
|
||||
description = "Calculus with Julia: Improper Integrals",
|
||||
tags = ["CalculusWithJulia", "integrals", "improper integrals"],
|
||||
);
|
||||
fig_size=(600, 400)
|
||||
fig_size=(800, 600)
|
||||
|
||||
nothing
|
||||
```
|
||||
@ -108,10 +108,8 @@ For the interval $(-\infty, \infty)$ we have need *both* these limits to exist,
|
||||
\int_{-\infty}^\infty f(x) dx = \lim_{M \rightarrow -\infty} \int_M^a f(x) dx + \lim_{M \rightarrow \infty} \int_a^M f(x) dx.
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""When the integral exists, it is said to *converge*. If it doesn't exist, it is said to *diverge*.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
When the integral exists, it is said to *converge*. If it doesn't exist, it is said to *diverge*.
|
||||
|
||||
##### Examples
|
||||
|
||||
@ -201,13 +199,8 @@ Suppose $a < c$, we define $\int_a^c f(x) dx = \lim_{M \rightarrow c-} \int_a^c
|
||||
= \lim_{M \rightarrow 0+} 2(1) - 2\sqrt{M} = 2.
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
|
||||
The cases $f(x) = x^{-n}$ for $n > 0$ are tricky to keep straight. For $n > 1$, the functions can be integrated over $[1,\infty)$, but not $(0,1]$. For $0 < n < 1$, the functions can be integrated over $(0,1]$ but not $[1, \infty)$.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The cases $f(x) = x^{-n}$ for $n > 0$ are tricky to keep straight. For $n > 1$, the functions can be integrated over $[1,\infty)$, but not $(0,1]$. For $0 < n < 1$, the functions can be integrated over $(0,1]$ but not $[1, \infty)$.
|
||||
|
||||
* Now consider $f(x) = 1/x$. Is this integral $\int_0^1 1/x \cdot dx$ defined? It will be *if* this limit exists:
|
||||
|
||||
@ -417,8 +410,8 @@ choices =[
|
||||
"It is convergent",
|
||||
"It is divergent",
|
||||
"Can't say"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -433,8 +426,8 @@ choices =[
|
||||
"It is convergent",
|
||||
"It is divergent",
|
||||
"Can't say"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
----
|
||||
@ -450,8 +443,8 @@ choices =[
|
||||
"It is convergent",
|
||||
"It is divergent",
|
||||
"Can't say"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
----
|
||||
@ -465,8 +458,8 @@ choices =[
|
||||
"It is convergent",
|
||||
"It is divergent",
|
||||
"Can't say"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
----
|
||||
@ -480,8 +473,8 @@ choices =[
|
||||
"It is convergent",
|
||||
"It is divergent",
|
||||
"Can't say"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -496,8 +489,8 @@ choices = [
|
||||
"``\\int_0^1 u^{2/3} \\cdot du``",
|
||||
"``\\int_0^\\infty 1/u \\cdot du``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
@ -13,10 +13,10 @@ using SymPy
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
using QuadGK
|
||||
|
||||
const frontmatter = (
|
||||
title = "Integration By Parts",
|
||||
description = "Calculus with Julia: Integration By Parts",
|
||||
tags = ["CalculusWithJulia", "integrals", "integration by parts"],
|
||||
frontmatter = (
|
||||
title = "Integration By Parts",
|
||||
description = "Calculus with Julia: Integration By Parts",
|
||||
tags = ["CalculusWithJulia", "integrals", "integration by parts"],
|
||||
);
|
||||
|
||||
nothing
|
||||
@ -41,21 +41,23 @@ Now we turn our attention to the implications of the *product rule*: $[uv]' = u'
|
||||
The following illustrates integration by parts of the integral $(uv)'$ over
|
||||
$[a,b]$ [original](http://en.wikipedia.org/wiki/Integration_by_parts#Visualization).
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
## parts picture
|
||||
u(x) = sin(x*pi/2)
|
||||
v(x) = x
|
||||
xs = range(0, stop=1, length=50)
|
||||
a,b = 1/4, 3/4
|
||||
p = plot(u, v, 0, 1, legend=false)
|
||||
plot!(p, zero, 0, 1)
|
||||
scatter!(p, [u(a), u(b)], [v(a), v(b)], color=:orange, markersize=5)
|
||||
```julia; echo=false
|
||||
let
|
||||
## parts picture
|
||||
u(x) = sin(x*pi/2)
|
||||
v(x) = x
|
||||
xs = range(0, stop=1, length=50)
|
||||
a,b = 1/4, 3/4
|
||||
p = plot(u, v, 0, 1, legend=false)
|
||||
plot!(p, zero, 0, 1)
|
||||
scatter!(p, [u(a), u(b)], [v(a), v(b)], color=:orange, markersize=5)
|
||||
|
||||
plot!(p, [u(a),u(a),0, 0, u(b),u(b),u(a)],
|
||||
[0, v(a), v(a), v(b), v(b), 0, 0],
|
||||
linetype=:polygon, fillcolor=:orange, alpha=0.25)
|
||||
annotate!(p, [(0.65, .25, "A"), (0.4, .55, "B")])
|
||||
annotate!(p, [(u(a),v(a) + .08, "(u(a),v(a))"), (u(b),v(b)+.08, "(u(b),v(b))")])
|
||||
plot!(p, [u(a),u(a),0, 0, u(b),u(b),u(a)],
|
||||
[0, v(a), v(a), v(b), v(b), 0, 0],
|
||||
linetype=:polygon, fillcolor=:orange, alpha=0.25)
|
||||
annotate!(p, [(0.65, .25, "A"), (0.4, .55, "B")])
|
||||
annotate!(p, [(u(a),v(a) + .08, "(u(a),v(a))"), (u(b),v(b)+.08, "(u(b),v(b))")])
|
||||
end
|
||||
```
|
||||
|
||||
The figure is a parametric plot of $(u,v)$ with the points $(u(a),
|
||||
@ -200,8 +202,8 @@ e^x(x^2 - 2x - 1) \big|_a^b.
|
||||
In fact, it isn't hard to see that an integral of $x^m e^x$, $m$ a positive integer, can be handled in this manner. For example, when $m=10$, `SymPy` gives:
|
||||
|
||||
```julia;
|
||||
@syms x
|
||||
integrate(x^10 * exp(x), x)
|
||||
@syms 𝒙
|
||||
integrate(𝒙^10 * exp(𝒙), 𝒙)
|
||||
```
|
||||
|
||||
|
||||
@ -264,7 +266,7 @@ by a double angle formula application, is $x/2 - \sin(2x)/4$.
|
||||
`SymPy` is quite able to do this repeated bookkeeping. For example with $n=10$:
|
||||
|
||||
```julia;
|
||||
integrate(cos(x)^10, x)
|
||||
integrate(cos(𝒙)^10, 𝒙)
|
||||
```
|
||||
|
||||
##### Example
|
||||
@ -403,17 +405,19 @@ When ``u(t)`` is strictly *increasing*, and hence having an inverse function, th
|
||||
|
||||
However, the correct answer requires understanding a minus sign. Consider the area enclosed by ``x(t) = \cos(t), y(t) = \sin(t)``:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
r(t) = [cos(t), sin(t)]
|
||||
p=plot_parametric(0..2pi, r, aspect_ratio=:equal, legend=false)
|
||||
for t ∈ (pi/4, 3pi/4, 5pi/4, 7pi/4)
|
||||
quiver!(unzip([r(t)])..., quiver=Tuple(unzip([0.1*r'(t)])))
|
||||
```julia; echo=false
|
||||
let
|
||||
r(t) = [cos(t), sin(t)]
|
||||
p=plot_parametric(0..2pi, r, aspect_ratio=:equal, legend=false)
|
||||
for t ∈ (pi/4, 3pi/4, 5pi/4, 7pi/4)
|
||||
quiver!(unzip([r(t)])..., quiver=Tuple(unzip([0.1*r'(t)])))
|
||||
end
|
||||
ti, tj = pi/3, pi/3+0.1
|
||||
plot!([cos(tj), cos(ti), cos(ti), cos(tj), cos(tj)], [0,0,sin(tj), sin(tj),0])
|
||||
quiver!([0],[0], quiver=Tuple(unzip([r(ti)])))
|
||||
quiver!([0],[0], quiver=Tuple(unzip([r(tj)])))
|
||||
p
|
||||
end
|
||||
ti, tj = pi/3, pi/3+0.1
|
||||
plot!([cos(tj), cos(ti), cos(ti), cos(tj), cos(tj)], [0,0,sin(tj), sin(tj),0])
|
||||
quiver!([0],[0], quiver=Tuple(unzip([r(ti)])))
|
||||
quiver!([0],[0], quiver=Tuple(unzip([r(tj)])))
|
||||
p
|
||||
```
|
||||
|
||||
|
||||
@ -441,10 +445,10 @@ This is a case of [Green's Theorem](https://en.wikipedia.org/wiki/Green%27s_theo
|
||||
Apply the formula to a parameterized circle to ensure, the signed area is properly computed. If we use ``x(t) = r\cos(t)`` and ``y(t) = r\sin(t)`` then we have the motion is counterclockwise:
|
||||
|
||||
```julia; hold=true
|
||||
@syms r t
|
||||
x(t) = r*cos(t)
|
||||
y(t) = r*sin(t)
|
||||
-integrate(y(t) * diff(x(t), t), (t, 0, 2PI))
|
||||
@syms 𝒓 t
|
||||
𝒙 = 𝒓 * cos(t)
|
||||
𝒚 = 𝒓 * sin(t)
|
||||
-integrate(𝒚 * diff(𝒙, t), (t, 0, 2PI))
|
||||
```
|
||||
|
||||
We see the expected answer for the area of a circle.
|
||||
@ -458,9 +462,9 @@ Working symbolically, we have one arch given by the following described in a *cl
|
||||
|
||||
```julia; hold=true
|
||||
@syms t
|
||||
x = t - sin(t)
|
||||
y = 1 - cos(t)
|
||||
integrate(y * diff(x, t), (t, 0, 2PI))
|
||||
𝒙 = t - sin(t)
|
||||
𝒚 = 1 - cos(t)
|
||||
integrate(𝒚 * diff(𝒙, t), (t, 0, 2PI))
|
||||
```
|
||||
|
||||
([Galileo](https://mathshistory.st-andrews.ac.uk/Curves/Cycloid/) was thwarted in finding this answer exactly and resorted to constructing one from metal to *estimate* the value.)
|
||||
@ -469,20 +473,24 @@ integrate(y * diff(x, t), (t, 0, 2PI))
|
||||
|
||||
Consider the example ``x(t) = \cos(t) + t\sin(t), y(t) = \sin(t) - t\cos(t)`` for ``0 \leq t \leq 2\pi``.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
x(t) = cos(t) + t*sin(t)
|
||||
y(t) = sin(t) - t*cos(t)
|
||||
ts = range(0,2pi, length=100)
|
||||
plot(x.(ts), y.(ts))
|
||||
```julia; echo=false
|
||||
let
|
||||
x(t) = cos(t) + t*sin(t)
|
||||
y(t) = sin(t) - t*cos(t)
|
||||
ts = range(0,2pi, length=100)
|
||||
plot(x.(ts), y.(ts))
|
||||
end
|
||||
```
|
||||
|
||||
How much area is enclosed by this curve and the ``x`` axis? The area is described in a counterclockwise manner, so we have:
|
||||
|
||||
```julia; hold=true
|
||||
x(t) = cos(t) + t*sin(t)
|
||||
y(t) = sin(t) - t*cos(t)
|
||||
yx′(t) = -y(t) * x'(t) # yx\prime[tab]
|
||||
quadgk(yx′, 0, 2pi)
|
||||
let
|
||||
x(t) = cos(t) + t*sin(t)
|
||||
y(t) = sin(t) - t*cos(t)
|
||||
yx′(t) = -y(t) * x'(t) # yx\prime[tab]
|
||||
quadgk(yx′, 0, 2pi)
|
||||
end
|
||||
```
|
||||
|
||||
This particular problem could also have been done symbolically, but many curves will need to have a numeric approximation used.
|
||||
@ -500,8 +508,8 @@ choices = [
|
||||
"``du=1/x dx \\quad v = x``",
|
||||
"``du=x\\log(x) dx\\quad v = 1``",
|
||||
"``du=1/x dx\\quad v = x^2/2``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -514,8 +522,8 @@ choices = [
|
||||
"``du=\\csc(x) dx \\quad v=\\sec(x)^3 / 3``",
|
||||
"``du=\\tan(x) dx \\quad v=\\sec(x)\\tan(x)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -530,8 +538,8 @@ choices = [
|
||||
"``du=-e^{-x} dx \\quad v=-\\sin(x)``",
|
||||
"``du=\\sin(x)dx \\quad v=-e^{-x}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -581,8 +589,8 @@ choices = [
|
||||
"``\\int (\\log(x))^{n+1}/(n+1) dx``",
|
||||
"``x(\\log(x))^n - \\int (\\log(x))^{n-1} dx``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -597,8 +605,8 @@ Consider the integral $\int x \cos(x) dx$. Which letter should be tried first?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["L", "I", "A", "T", "E"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
----
|
||||
@ -608,8 +616,8 @@ Consider the integral $\int x^2\log(x) dx$. Which letter should be tried first?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["L", "I", "A", "T", "E"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
----
|
||||
@ -619,8 +627,8 @@ Consider the integral $\int x^2 \sin^{-1}(x) dx$. Which letter should be tried f
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["L", "I", "A", "T", "E"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -631,8 +639,8 @@ Consider the integral $\int e^x \sin(x) dx$. Which letter should be tried first?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["L", "I", "A", "T", "E"]
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -644,6 +652,6 @@ choices = [
|
||||
"``x\\cos^{-1}(x)-\\sqrt{1 - x^2}``",
|
||||
"``x^2/2 \\cos^{-1}(x) - x\\sqrt{1-x^2}/4 - \\cos^{-1}(x)/4``",
|
||||
"``-\\sin^{-1}(x)``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -98,10 +98,12 @@ Though not continuous, $f(x)$ is integrable as it contains only jumps. The integ
|
||||
What is the average value of the function $e^{-x}$ between $0$ and $\log(2)$?
|
||||
|
||||
```math
|
||||
\text{average} = \frac{1}{\log(2) - 0} \int_0^{\log(2)} e^{-x} dx
|
||||
= \frac{1}{\log(2)} (-e^{-x}) \big|_0^{\log(2)}
|
||||
= -\frac{1}{\log(2)} (\frac{1}{2} - 1)
|
||||
= \frac{1}{2\log(2)}.
|
||||
\begin{align*}
|
||||
\text{average} = \frac{1}{\log(2) - 0} \int_0^{\log(2)} e^{-x} dx\\
|
||||
&= \frac{1}{\log(2)} (-e^{-x}) \big|_0^{\log(2)}\\
|
||||
&= -\frac{1}{\log(2)} (\frac{1}{2} - 1)\\
|
||||
&= \frac{1}{2\log(2)}.
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
Visualizing, we have
|
||||
@ -214,8 +216,8 @@ choices = [
|
||||
"``\\int_0^t (v(0) + v(u))/2 du = v(0)/2\\cdot t + x(u)/2\\ \\big|_0^t``",
|
||||
"``(v(0) + v(t))/2 \\cdot \\int_0^t du = (v(0) + v(t))/2 \\cdot t``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -278,8 +280,8 @@ value of $g(x) = \lvert x \rvert$ over the interval $[0,1]$?
|
||||
choices = [
|
||||
L"That of $f(x) = x^{10}$.",
|
||||
L"That of $g(x) = \lvert x \rvert$."]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -297,8 +299,8 @@ choices = [
|
||||
]
|
||||
n1, _ = quadgk(x -> x^2 *(1-x)^3, 0, 1)
|
||||
n2, _ = quadgk(x -> x^3 *(1-x)^4, 0, 1)
|
||||
ans = 1 + (n1 < n2)
|
||||
radioq(choices, ans)
|
||||
answ = 1 + (n1 < n2)
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -324,8 +326,8 @@ choices = [
|
||||
L"Because the mean value theorem says this is $f(c) (x-a)$ for some $c$ and both terms are positive by the assumptions",
|
||||
"Because the definite integral is only defined for positive area, so it is always positive"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
* Explain why $F(x)$ is increasing.
|
||||
@ -336,8 +338,8 @@ L"By the extreme value theorem, $F(x)$ must reach its maximum, hence it must inc
|
||||
L"By the intermediate value theorem, as $F(x) > 0$, it must be true that $F(x)$ is increasing",
|
||||
L"By the fundamental theorem of calculus, part I, $F'(x) = f(x) > 0$, hence $F(x)$ is increasing"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -354,6 +356,6 @@ choices = [
|
||||
L"The average of $f$",
|
||||
L"The exponential of the average of $\log(f)$"
|
||||
]
|
||||
ans = val1 > val2 ? 1 : 2
|
||||
radioq(choices, ans)
|
||||
answ = val1 > val2 ? 1 : 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -75,15 +75,10 @@ The value of this decomposition is that the terms $a_{ij}(x)/q_i(x)^j$
|
||||
each have an antiderivative, and so the sum of them will also have an
|
||||
antiderivative.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
|
||||
Many calculus texts will give some examples for finding a partial
|
||||
fraction decomposition. We push that work off to `SymPy`, as for all
|
||||
but the easiest cases - a few are in the problems - it can be a bit tedious.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Many calculus texts will give some examples for finding a partial
|
||||
fraction decomposition. We push that work off to `SymPy`, as for all
|
||||
but the easiest cases - a few are in the problems - it can be a bit tedious.
|
||||
|
||||
In `SymPy`, the `apart` function will find the partial fraction
|
||||
decomposition when a factorization is available. For example, here we see $n_i$ terms for each power of
|
||||
@ -418,8 +413,8 @@ choices = [
|
||||
L"The value $c$ is a removable singularity, so the integral will be identical.",
|
||||
L"The resulting function has an identical domain and is equivalent for all $x$."
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -431,8 +426,8 @@ choices = [
|
||||
L"The value $c$ is a removable singularity, so the integral will be identical.",
|
||||
L"The resulting function has an identical domain and is equivalent for all $x$."
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -444,8 +439,8 @@ choices = [
|
||||
L"The value $c$ is a removable singularity, so the integral will be identical.",
|
||||
L"The resulting function has an identical domain and is equivalent for all $x$."
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -247,8 +247,12 @@ But $u^3/3 - 4u/3 = (1/3) \cdot u(u-1)(u+2)$, so between $-2$ and $0$
|
||||
it is positive and between $0$ and $1$ negative, so this integral is:
|
||||
|
||||
```math
|
||||
\int_{-2}^0 (u^3/3 - 4u/3 ) du + \int_{0}^1 -(u^3/3 - 4u/3) du =
|
||||
(\frac{u^4}{12} - \frac{4}{3}\frac{u^2}{2}) \big|_{-2}^0 - (\frac{u^4}{12} - \frac{4}{3}\frac{u^2}{2}) \big|_{0}^1 = \frac{4}{3} - -\frac{7}{12} = \frac{23}{12}.
|
||||
\begin{align*}
|
||||
\int_{-2}^0 (u^3/3 - 4u/3 ) du + \int_{0}^1 -(u^3/3 - 4u/3) du
|
||||
&= (\frac{u^4}{12} - \frac{4}{3}\frac{u^2}{2}) \big|_{-2}^0 - (\frac{u^4}{12} - \frac{4}{3}\frac{u^2}{2}) \big|_{0}^1\\
|
||||
&= \frac{4}{3} - -\frac{7}{12}\\
|
||||
&= \frac{23}{12}.
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
##### Example
|
||||
@ -400,13 +404,11 @@ Finally, we put back in the `u(x)` to get an antiderivative.
|
||||
ex₃(w => u(x))
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
Lest it be thought this is an issue with `SymPy`, but not other
|
||||
systems, this example was [borrowed](http://faculty.uml.edu/jpropp/142/Integration.pdf) from an
|
||||
illustration for helping Mathematica.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Lest it be thought this is an issue with `SymPy`, but not other
|
||||
systems, this example was [borrowed](http://faculty.uml.edu/jpropp/142/Integration.pdf) from an
|
||||
illustration for helping Mathematica.
|
||||
|
||||
|
||||
## Trigonometric substitution
|
||||
|
||||
@ -563,8 +565,8 @@ choices = [
|
||||
"``\\int u (1 - u^2) du``",
|
||||
"``\\int u \\cos(x) du``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -578,8 +580,8 @@ choices = [
|
||||
"``u=\\sec(x)``",
|
||||
"``u=\\sec(x)^2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -593,8 +595,8 @@ choices = [
|
||||
"``u=\\sqrt{x^2 - 1}``",
|
||||
"``u=x``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
###### Question
|
||||
|
||||
@ -620,8 +622,8 @@ choices = [
|
||||
"``\\int u du``",
|
||||
"``\\int u^3/x du``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
###### Question
|
||||
|
||||
@ -633,8 +635,8 @@ choices = [
|
||||
"``u=\\sin(x)``",
|
||||
"``u=\\tan(x)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -654,8 +656,8 @@ choices = [
|
||||
"``a=0,~ b=0``",
|
||||
"``a=1,~ b=1``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -669,8 +671,8 @@ choices = [
|
||||
"``\\sec(u) = x``",
|
||||
"``u = 1 - x^2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -684,8 +686,8 @@ choices = [
|
||||
"``\\tan(u) = x``",
|
||||
"``\\sec(u) = x``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -699,8 +701,8 @@ choices = [
|
||||
"``\\sec(u) = x``",
|
||||
"``u = 1 - x^2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -715,8 +717,8 @@ choices = [
|
||||
"``\\sec(u) = x``",
|
||||
"``4\\sin(u) = x``",
|
||||
"``\\sin(u) = x``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -730,8 +732,8 @@ choices = [
|
||||
"``\\tan(u) = x``",
|
||||
"``a\\sec(u) = x``",
|
||||
"``\\sec(u) = x``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -751,8 +753,8 @@ choices =[
|
||||
"``a=\\pi/3,~ b=\\pi/2``",
|
||||
"``a=1/2,~ b= 1``"
|
||||
]
|
||||
ans =1
|
||||
radioq(choices, ans)
|
||||
answ =1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -763,6 +765,6 @@ How would we verify that $\log\lvert (\sec(u) + \tan(u))\rvert$ is an antideriva
|
||||
choices = [
|
||||
L"We could differentiate $\sec(u)$.",
|
||||
L"We could differentiate $\log\lvert (\sec(u) + \tan(u))\rvert$ "]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -17,7 +17,7 @@ const frontmatter = (
|
||||
description = "Calculus with Julia: Surface Area",
|
||||
tags = ["CalculusWithJulia", "integrals", "surface area"],
|
||||
);
|
||||
fig_size=(600, 400)
|
||||
fig_size=(800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
@ -174,11 +174,13 @@ formula, even though we just saw how to get this value.
|
||||
A cone be be envisioned as rotating the function $f(x) = x\tan(\theta)$ between $0$ and $h$ around the $x$ axis. This integral yields the surface area:
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
\int_0^h 2\pi f(x) \sqrt{1 + f'(x)^2}dx
|
||||
= \int_0^h 2\pi x \tan(\theta) \sqrt{1 + \tan(\theta)^2}dx
|
||||
= (2\pi\tan(\theta)\sqrt{1 + \tan(\theta)^2} x^2/2 \big|_0^h
|
||||
= \pi \tan(\theta) \sec(\theta) h^2
|
||||
= \pi r^2 / \sin(\theta).
|
||||
&= \int_0^h 2\pi x \tan(\theta) \sqrt{1 + \tan(\theta)^2}dx \\
|
||||
&= (2\pi\tan(\theta)\sqrt{1 + \tan(\theta)^2} x^2/2 \big|_0^h \\
|
||||
&= \pi \tan(\theta) \sec(\theta) h^2 \\
|
||||
&= \pi r^2 / \sin(\theta).
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
(There are many ways to express this, we used $r$ and $\theta$ to
|
||||
@ -449,8 +451,8 @@ choices = [
|
||||
"``-\\int_1^{_1} 2\\pi u \\sqrt{1 + u^2} du``",
|
||||
"``-\\int_1^{_1} 2\\pi u^2 \\sqrt{1 + u} du``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Though the integral can be computed by hand, give a numeric value.
|
||||
@ -506,8 +508,8 @@ choices = [
|
||||
"``\\int_u^{u_h} 2\\pi y dx``",
|
||||
"``\\int_u^{u_h} 2\\pi x dx``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Questions
|
||||
|
||||
@ -105,13 +105,8 @@ area is $\pi r(x)^2$ so the volume is given by:
|
||||
V = \int_a^b \pi r(x)^2 dx.
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
|
||||
The formula is for a rotation around the $x$-axis, but can easily be generalized to rotating around any line (say the $y$-axis or $y=x$, ...) just by adjusting what $r(x)$ is taken to be.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The formula is for a rotation around the $x$-axis, but can easily be generalized to rotating around any line (say the $y$-axis or $y=x$, ...) just by adjusting what $r(x)$ is taken to be.
|
||||
|
||||
|
||||
For a numeric example, we consider the original Red
|
||||
@ -136,8 +131,8 @@ This is
|
||||
|
||||
```julia;
|
||||
d0, d1, h = 2.5, 3.75, 4.75
|
||||
r(x) = d0/2 + (d1/2 - d0/2)/h * x
|
||||
vol, _ = quadgk(x -> pi * r(x)^2, 0, h)
|
||||
rad(x) = d0/2 + (d1/2 - d0/2)/h * x
|
||||
vol, _ = quadgk(x -> pi * rad(x)^2, 0, h)
|
||||
```
|
||||
|
||||
So $36.9 \text{in}^3$. How many ounces is that? It is useful to know
|
||||
@ -178,7 +173,7 @@ So we need to solve $v \cdot (231/128) = \int_0^h\pi r(x)^2 dx$ for $h$ when $v=
|
||||
Let's express volume as a function of $h$:
|
||||
|
||||
```julia;
|
||||
Vol(h) = quadgk(x -> pi * r(x)^2, 0, h)[1]
|
||||
Vol(h) = quadgk(x -> pi * rad(x)^2, 0, h)[1]
|
||||
```
|
||||
|
||||
Then to solve we have:
|
||||
@ -201,12 +196,8 @@ As a percentage of the total height, these are:
|
||||
h5/h, h12/h
|
||||
```
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
Were performance at issue, Newton's method might also have been considered here, as the derivative is easily computed by the fundamental theorem of calculus.
|
||||
""")
|
||||
```
|
||||
|
||||
!!! note
|
||||
Were performance at issue, Newton's method might also have been considered here, as the derivative is easily computed by the fundamental theorem of calculus.
|
||||
|
||||
##### Example
|
||||
|
||||
@ -239,16 +230,11 @@ quadgk(x -> pi*radius(x)^2, 1, Inf)[1]
|
||||
|
||||
That is a value very reminiscent of $\pi$, which it is as $\int_1^\infty 1/x^2 dx = -1/x\big|_1^\infty=1$.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
|
||||
The interest in this figure is that soon we will be able to show that
|
||||
it has **infinite** surface area, leading to the
|
||||
[paradox](http://tinyurl.com/osawwqm) that it seems possible to fill
|
||||
it with paint, but not paint the outside.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The interest in this figure is that soon we will be able to show that
|
||||
it has **infinite** surface area, leading to the
|
||||
[paradox](http://tinyurl.com/osawwqm) that it seems possible to fill
|
||||
it with paint, but not paint the outside.
|
||||
|
||||
##### Example
|
||||
|
||||
@ -668,8 +654,8 @@ choices = [
|
||||
"``1/3 \\cdot w^2\\cdot h``",
|
||||
"``l\\cdot w \\cdot h/ 3``"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -696,8 +682,8 @@ choices = [
|
||||
"``4/3 \\cdot \\pi a^2 b``",
|
||||
"``\\pi/3 \\cdot a b^2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -752,9 +738,9 @@ Find the volume of rotating the region bounded by the line $y=x$, $x=1$ and the
|
||||
```julia; hold=true; echo=false
|
||||
cm=[2/3, 1/3]
|
||||
c = [1/2, 1/2]
|
||||
r = norm(cm - c)
|
||||
rr = norm(cm - c)
|
||||
A = 1/2 * 1 * 1
|
||||
val = 2pi*r*A
|
||||
val = 2pi * rr * A
|
||||
numericq(val)
|
||||
```
|
||||
|
||||
|
||||
@ -86,12 +86,10 @@ continuity and *left* continuity at a point, where the limit in the
|
||||
defintion is replaced by a right or left limit, as appropriate.
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
alert("""
|
||||
The limit in the definition of continuity is the basic limit and not an extended sense where
|
||||
infinities are accounted for.
|
||||
""")
|
||||
```
|
||||
!!! warning
|
||||
The limit in the definition of continuity is the basic limit and not an extended sense where
|
||||
infinities are accounted for.
|
||||
|
||||
##### Examples of continuity
|
||||
|
||||
Most familiar functions are continuous everywhere.
|
||||
@ -256,8 +254,8 @@ f+g,~ f-g,~ f\cdot g,~ f\circ g,~ f/g
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``f+g``", "``f-g``", "``f\\cdot g``", "``f\\circ g``", "``f/g``"]
|
||||
ans = length(choices)
|
||||
radioq(choices, ans)
|
||||
answ = length(choices)
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -268,16 +266,16 @@ When will $f\circ g$ be continuous?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [L"For all $x$", L"For all $x > 0$", L"For all $x$ where $\sin(x) > 0$"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
When will $g \circ f$ be continuous?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [L"For all $x$", L"For all $x > 0$", L"For all $x$ where $\sin(x) > 0$"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -290,8 +288,8 @@ L"The function $g$ is continuous everywhere",
|
||||
L"The function $f$ is continuous everywhere",
|
||||
L"The function $g$ is continuous everywhere and $f$ is continuous on the range of $g$",
|
||||
L"The function $f$ is continuous everywhere and $g$ is continuous on the range of $f$"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -304,8 +302,8 @@ L"When $x > 2$",
|
||||
L"When $x \geq 2$",
|
||||
L"When $x \leq 2$",
|
||||
L"For $x \geq 0$"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -375,8 +373,8 @@ Suppose $f(x)$, $g(x)$, and $h(x)$ are continuous functions on $(a,b)$. If $a <
|
||||
choices = [L"No, as $g(c)$ may not be in the interval $(a,b)$",
|
||||
"Yes, composition of continuous functions results in a continuous function, so the limit is just the function value."
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -446,6 +444,6 @@ choices = ["Can't tell",
|
||||
"``-1.0``",
|
||||
"``0.0``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -7,8 +7,6 @@ using CalculusWithJulia
|
||||
using Plots
|
||||
using Roots
|
||||
using SymPy
|
||||
import IntervalArithmetic
|
||||
import IntervalRootFinding
|
||||
```
|
||||
|
||||
```julia; echo=false; results="hidden"
|
||||
@ -20,7 +18,7 @@ const frontmatter = (
|
||||
tags = ["CalculusWithJulia", "limits", "implications of continuity"],
|
||||
);
|
||||
|
||||
const fig_size=(400, 400)
|
||||
fig_size=(800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
@ -237,20 +235,16 @@ sin(c)
|
||||
### The `find_zero` function.
|
||||
|
||||
The `Roots` package has a function `find_zero` that implements the
|
||||
bisection method when called as `find_zero(f, a..b)` where $[a,b]$
|
||||
bisection method when called as `find_zero(f, (a,b))` where $[a,b]$
|
||||
is a bracket. Its use is similar to `simple_bisection` above. This package is loaded when `CalculusWithJulia` is. We illlustrate the usage of `find_zero`
|
||||
in the following:
|
||||
|
||||
```julia;
|
||||
xstar = find_zero(sin, 3..4)
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
alert("""
|
||||
Notice, the call `find_zero(sin, 3..4)` again fits the template `action(function, args...)` that we see repeatedly. The `find_zero` function can also be called through `fzero`. The use of `3..4` to specify the interval is not necessary. For example `(3,4)` or `[3,4]` would work equally as well. The `..` is an idiom in `Julia` for intervals, so used here, but is not part of the base language. It is imported from `EllipsisNotation` by the `CalculusWithJulia` package.
|
||||
""")
|
||||
xstar = find_zero(sin, (3, 4))
|
||||
```
|
||||
|
||||
!!! warning
|
||||
Notice, the call `find_zero(sin, (3, 4))` again fits the template `action(function, args...)` that we see repeatedly. The `find_zero` function can also be called through `fzero`. The use of `(3, 4)` to specify the interval is not necessary. For example `[3,4]` would work equally as well. (Anything where `extrema` is defined works.)
|
||||
|
||||
This function utilizes some facts about floating point values to
|
||||
guarantee that the answer will be an *exact* zero or a value where there is a sign change between the next bigger floating point or the next smaller, which means the sign at the next and previous floating point values is different:
|
||||
@ -265,7 +259,7 @@ The polynomial $p(x) = x^5 - x + 1$ has a zero between $-2$ and $-1$. Find it.
|
||||
|
||||
```julia;
|
||||
p(x) = x^5 - x + 1
|
||||
c₀ = find_zero(p, -2 .. -1) # avoiding ..-1 which errors
|
||||
c₀ = find_zero(p, (-2, -1))
|
||||
(c₀, p(c₀))
|
||||
```
|
||||
|
||||
@ -289,7 +283,7 @@ plot(q, 5, 10)
|
||||
Find the zero numerically. The plot shows $q(5) < 0 < q(10)$, so $[5,10]$ is a bracket. We thus have:
|
||||
|
||||
```julia;
|
||||
find_zero(q, 5..10)
|
||||
find_zero(q, (5, 10))
|
||||
```
|
||||
|
||||
|
||||
@ -310,7 +304,7 @@ plot(x^3 - x + 1, -3, 3)
|
||||
It appears (and a plot over $[0,1]$ verifies) that there is one zero between $-2$ and $-1$. It is found with:
|
||||
|
||||
```julia;
|
||||
find_zero(x^3 - x + 1, -2 .. -1)
|
||||
find_zero(x^3 - x + 1, (-2, -1))
|
||||
```
|
||||
|
||||
|
||||
@ -333,7 +327,7 @@ We see from the graph that it is clearly between $0$ and $2$, so all we need is
|
||||
|
||||
```julia;
|
||||
𝒉(x) = 𝒇(x) - 𝒈(x)
|
||||
find_zero(𝒉, 0..2)
|
||||
find_zero(𝒉, (0, 2))
|
||||
```
|
||||
|
||||
#### Using parameterized functions (`f(x,p)`) with `find_zero`
|
||||
@ -342,7 +336,7 @@ Geometry will tell us that ``\cos(x) = x/p`` for *one* ``x`` in ``[0, \pi/2]`` w
|
||||
|
||||
```julia; hold=true;
|
||||
f(x, p=1) = cos(x) - x/p
|
||||
I = 0..pi/2
|
||||
I = (0, pi/2)
|
||||
find_zero(f, I), find_zero(f, I, p=2)
|
||||
```
|
||||
|
||||
@ -385,7 +379,7 @@ cheaper.
|
||||
Let's get a numeric value, using a simple bracket and an anonymous function:
|
||||
|
||||
```julia;
|
||||
find_zero(x -> plan1(x) - plan2(x), 10..20)
|
||||
find_zero(x -> plan1(x) - plan2(x), (10, 20))
|
||||
```
|
||||
|
||||
##### Example, the flight of an arrow
|
||||
@ -480,7 +474,7 @@ d(b)
|
||||
From the graph, we can see the zero is around `b`. As `y(b)` is `-Inf` we can use the bracket `(b/2,b)`
|
||||
|
||||
```julia;
|
||||
x1 = find_zero(d, (b/2)..b)
|
||||
x1 = find_zero(d, (b/2, b))
|
||||
```
|
||||
|
||||
The answer is approximately $140.7$
|
||||
@ -527,7 +521,7 @@ does the algorithm yield:
|
||||
|
||||
```julia;
|
||||
fᵢ(x) = 1/x
|
||||
x0 = find_zero(fᵢ, -1..1)
|
||||
x0 = find_zero(fᵢ, (-1, 1))
|
||||
```
|
||||
|
||||
|
||||
@ -559,31 +553,25 @@ interval.
|
||||
|
||||
Still, with some engineering, this can be a useful approach, save the
|
||||
caveats. This idea is implemented in the `find_zeros` function of the `Roots` package. The function is
|
||||
called via `find_zeros(f, a..b)` but here the interval
|
||||
called via `find_zeros(f, (a, b))` but here the interval
|
||||
$[a,b]$ is not necessarily a bracketing interval.
|
||||
|
||||
To see, we have:
|
||||
|
||||
```julia; hold=true;
|
||||
f(x) = cos(10*pi*x)
|
||||
find_zeros(f, 0..1)
|
||||
find_zeros(f, (0, 1))
|
||||
```
|
||||
|
||||
Or for a polynomial:
|
||||
|
||||
```julia; hold=true;
|
||||
f(x) = x^5 - x^4 + x^3 - x^2 + 1
|
||||
find_zeros(f, -10..10)
|
||||
find_zeros(f, (-10, 10))
|
||||
```
|
||||
|
||||
(Here $-10$ and $10$ were arbitrarily chosen. Cauchy's method could be used to be more systematic.)
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
At the end of this section are details on how to use the `IntervalRootFinding` package to identify all zeros in a specified interval. This package offers a more robust algorithm for this task.
|
||||
""")
|
||||
```
|
||||
|
||||
##### Example: Solving f(x) = g(x)
|
||||
|
||||
Use `find_zeros` to find when $e^x = x^5$ in the interval $[-20, 20]$. Verify the answers.
|
||||
@ -593,7 +581,7 @@ The zeros are then found with:
|
||||
|
||||
```julia;
|
||||
f₁(x) = exp(x) - x^5
|
||||
zs = find_zeros(f₁, -20..20)
|
||||
zs = find_zeros(f₁, (-20,20))
|
||||
```
|
||||
|
||||
|
||||
@ -760,7 +748,7 @@ $f(x) = e^x - x^4$. Find its value numerically:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
f(x) = exp(x) - x^4
|
||||
val = find_zero(f, -10..0);
|
||||
val = find_zero(f, (-10, 0));
|
||||
numericq(val, 1e-3)
|
||||
```
|
||||
|
||||
@ -772,7 +760,7 @@ $f(x) = e^x - x^4$. Find its value numerically:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
f(x) = exp(x) - x^4
|
||||
val = find_zero(f, 0..5);
|
||||
val = find_zero(f, (0, 5));
|
||||
numericq(val, 1e-3)
|
||||
```
|
||||
|
||||
@ -786,7 +774,7 @@ zeros on the positive $x$ axis. You are asked to find the largest
|
||||
```julia; hold=true; echo=false
|
||||
b = 10
|
||||
f(x) = x^2 - b * x * log(x)
|
||||
val = find_zero(f, 10..500)
|
||||
val = find_zero(f, (10, 500))
|
||||
numericq(val, 1e-3)
|
||||
```
|
||||
|
||||
@ -805,7 +793,7 @@ plot(airyai, -10, 10) # `airyai` loaded in `SpecialFunctions` by `CalculusWith
|
||||
The second largest root is:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
val = find_zero(airyai, -5 .. -4);
|
||||
val = find_zero(airyai, (-5, -4));
|
||||
numericq(val, 1e-8)
|
||||
```
|
||||
|
||||
@ -816,7 +804,7 @@ numericq(val, 1e-8)
|
||||
Certainly $x^3$ equals $3^x$ at $x=3$. Find the largest value for which $x^3 = 3x$.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
val = maximum(find_zeros(x -> x^3 - 3^x, 0..20))
|
||||
val = maximum(find_zeros(x -> x^3 - 3^x, (0, 20)))
|
||||
numericq(val)
|
||||
```
|
||||
|
||||
@ -824,8 +812,8 @@ Compare $x^2$ and $2^x$. They meet at $2$, where do the meet again?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["Only before 2", "Only after 2", "Before and after 2"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Just by graphing, find a number in $b$ with $2 < b < 3$ where for
|
||||
@ -837,8 +825,8 @@ choices=[
|
||||
"``b \\approx 2.5``",
|
||||
"``b \\approx 2.7``",
|
||||
"``b \\approx 2.9``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -882,8 +870,8 @@ Let $v_0= 390$. The three times in question can be found from the zeros of `f` a
|
||||
choices = ["``(0.0, 12.1875, 24.375)``",
|
||||
"``(-4.9731, 0.0, 4.9731)``",
|
||||
"``(0.0, 625.0, 1250.0)``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -915,13 +903,13 @@ ground.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
t0 = 0.0
|
||||
tf = find_zero(h, 10..20)
|
||||
ta = find_zero(D(h), t0..tf)
|
||||
tf = find_zero(h, (10, 20))
|
||||
ta = find_zero(D(h), (t0, tf))
|
||||
choices = ["``(0, 13.187, 30.0)``",
|
||||
"``(0, 32.0, 390.0)``",
|
||||
"``(0, 2.579, 13.187)``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -932,7 +920,7 @@ Part of the proof of the intermediate value theorem rests on knowing what the li
|
||||
choices = [L"It must be that $L > y$ as each $f(x)$ is.",
|
||||
L"It must be that $L \geq y$",
|
||||
L"It can happen that $L < y$, $L=y$, or $L>y$"]
|
||||
ans = 2
|
||||
answ = 2
|
||||
radioq(choices, 2, keep_order=true)
|
||||
```
|
||||
|
||||
@ -949,8 +937,8 @@ choices = [
|
||||
"``f(x) = \\sin(x),~ I=(-\\pi, \\pi)``",
|
||||
"``f(x) = \\sin(x),~ I=(-\\pi/2, \\pi/2)``",
|
||||
"None of the above"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -966,8 +954,8 @@ choices = [
|
||||
"``f(x) = 1/x,~ I=[-2, -1]``",
|
||||
"``f(x) = 1/x,~ I=[-1, 1]``",
|
||||
"none of the above"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -984,8 +972,8 @@ choices = [
|
||||
"``f(x) = 1/x,~ I=[-4, -1]``",
|
||||
"``f(x) = \\text{floor}(x),~ I=[-1/2, 1/2]``",
|
||||
"none of the above"]
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1024,8 +1012,8 @@ L"There is no value $c$ for which $f(c)$ is an absolute maximum over $I$.",
|
||||
L"There is just one value of $c$ for which $f(c)$ is an absolute maximum over $I$.",
|
||||
L"There are many values of $c$ for which $f(c)$ is an absolute maximum over $I$."
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1039,8 +1027,8 @@ L"There is no value $M$ for which $M=f(c)$, $c$ in $I$ for which $M$ is an absol
|
||||
L"There is just one value $M$ for which $M=f(c)$, $c$ in $I$ for which $M$ is an absolute maximum over $I$.",
|
||||
L"There are many values $M$ for which $M=f(c)$, $c$ in $I$ for which $M$ is an absolute maximum over $I$."
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -1056,8 +1044,8 @@ choices = [
|
||||
"``f(x) = \\sin(x),\\quad I=[-\\pi/2, \\pi/2]``",
|
||||
"``f(x) = \\sin(x),\\quad I=[0, 2\\pi]``",
|
||||
"``f(x) = \\sin(x),\\quad I=[-2\\pi, 2\\pi]``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
@ -1065,7 +1053,7 @@ radioq(choices, ans)
|
||||
The zeros of the equation $\cos(x) \cdot \cosh(x) = 1$ are related to vibrations of rods. Using `find_zeros`, what is the largest zero in the interval $[0, 6\pi]$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
val = maximum(find_zeros(x -> cos(x) * cosh(x) - 1, 0..6pi))
|
||||
val = maximum(find_zeros(x -> cos(x) * cosh(x) - 1, (0, 6pi)))
|
||||
numericq(val)
|
||||
```
|
||||
|
||||
@ -1086,98 +1074,3 @@ a,b = 1, 2
|
||||
k_x, k_y = 3, 4
|
||||
plot(t -> a * cos(k_x *t), t-> b * sin(k_y * t), 0, 4pi)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
## Using `IntervalRootFinding` to identify zeros
|
||||
|
||||
The `IntervalRootFinding` package provides a more *rigorous* alternative to `find_zeros`. This packages leverages the interval arithmetic features of `IntervalArithmetic`.
|
||||
The `IntervalRootFinding` package provides a function `roots`, with usage similar to `find_zeros`. Intervals are specified with the notation `a..b`. In the following, we *qualify* `roots` to not conflict with the `roots` function from `SymPy`, which has already been loaded:
|
||||
|
||||
```julia
|
||||
u(x) = sin(x) - 0.1*x^2 + 1
|
||||
𝑱 = IntervalArithmetic.Interval(-10, 10) # cumbersome -10..10; needed here: .. means something in CalculusWithJulia
|
||||
rts = IntervalRootFinding.roots(u, 𝑱)
|
||||
```
|
||||
|
||||
The "zeros" are returned with an enclosing interval and a flag, which for the above indicates a unique zero in the interval.
|
||||
|
||||
The intervals with a unique answer can be filtered and refined with a construct like the following:
|
||||
|
||||
```julia
|
||||
[find_zero(u, (IntervalArithmetic.interval(I).lo, IntervalArithmetic.interval(I).hi)) for I in rts if I.status == :unique]
|
||||
```
|
||||
|
||||
The midpoint of the returned interval can be found by composing the `mid` function with the `interval` function of the package:
|
||||
|
||||
```julia
|
||||
[(IntervalArithmetic.mid ∘ IntervalArithmetic.interval)(I) for I in rts if I.status == :unique]
|
||||
```
|
||||
|
||||
|
||||
|
||||
For some problems, `find_zeros` is more direct, as with this one:
|
||||
|
||||
|
||||
```julia
|
||||
find_zeros(u, -10..10)
|
||||
```
|
||||
|
||||
Which can be useful if there is some prior understanding of the zeros expected to be found.
|
||||
However, `IntervalRootFinding` is more efficient computationally and *offers a guarantee* on the values found.
|
||||
|
||||
|
||||
|
||||
For functions where roots are not "unique" a different output may appear:
|
||||
|
||||
```julia; hold=true;
|
||||
f(x) = x*(x-1)^2
|
||||
rts = IntervalRootFinding.roots(f, 𝑱)
|
||||
```
|
||||
|
||||
The interval labeled `:unknown` contains a `0`, but it can't be proved by `roots`.
|
||||
|
||||
|
||||
Interval arithmetic finds **rigorous** **bounds** on the range of `f` values over a closed interval `a..b` (the range is `f(a..b)`). "Rigorous" means the bounds are truthful and account for possible floating point issues. "Bounds" means the answer lies within, but the bound need not be the answer.
|
||||
|
||||
This allows one -- for some functions -- to answer affirmatively questions like:
|
||||
|
||||
* Is the function *always* positive on `a..b`? Negative? This can be done by checking if `0` is in the bound given by `f(a..b)`. If it isn't then one of the two characterizations is true.
|
||||
|
||||
* Is the function *strictly increasing* on `a..b`? Strictly decreasing? These questions can be answered using the (upcoming) [derivative](../derivatives/derivatives.html). If the derivative is positive on `a..b` then `f` is strictly increasing, if negative on `a..b` then `f` is strictly decreasing. Finding the derivative can be done within the `IntervalArithmetic` framework using [automatic differentiation](../derivatives/numeric_derivatives.html), a blackbox operation denoted `f'` below.
|
||||
|
||||
Combined, for some functions and some intervals these two questions can be answered affirmatively:
|
||||
|
||||
* the interval does not contain a zero (`0 !in f(a..b)`)
|
||||
* over the interval, the function crosses the `x` axis *once* (`f(a..a)` and `f(b..b)` are one positive and one negative *and* `f` is strictly monotone, or `0 !in f'(a..b)`)
|
||||
|
||||
This allows the following (simplified) bisection-like algorithm to be used:
|
||||
|
||||
* consider an interval `a..b`
|
||||
* if the function is *always* positive or negative, it can be discarded as no zero can be in the interval
|
||||
* if the function crosses the `x` axis *once* over this interval **then** there is a "unique" zero in the interval and the interval can be marked so and set aside
|
||||
* if neither of the above *and* `a..b` is not too small already, then *sub-divide* the interval and repeat the above with *both* smaller intervals
|
||||
* if `a..b` is too small, stop and mark it as "unknown"
|
||||
|
||||
When terminated there will be intervals with unique zeros flagged and smaller intervals with an unknown status.
|
||||
|
||||
Compared to the *bisection* algorithm -- which only knows for some intervals if that interval has one or more crossings -- this algorithm gives a more rigorous means to get all the zeros in `a..b`.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
For a last example of the value of this package, this function, which appeared in our discussion on limits, is *positive* for **every** floating point number, but has two zeros snuck in at values within the floating point neighbors of $15/11$
|
||||
|
||||
```julia
|
||||
t(x) = x^2 + 1 +log(abs( 11*x-15 ))/99
|
||||
```
|
||||
|
||||
The `find_zeros` function will fail on identifying any potential zeros of this function. Even the basic call of `roots` will fail, due to it relying on some smoothness of `f`. However, explicitly asking for `Bisection` shows the *potential* for one or more zeros near $15/11$:
|
||||
|
||||
```julia
|
||||
IntervalRootFinding.roots(t, 𝑱, IntervalRootFinding.Bisection)
|
||||
```
|
||||
|
||||
(The basic algorithm above can be sped up using a variant of [Newton's](../derivatives/newton_method.html) method, this variant assumes some "smoothness" in the function `f`, whereas this `f` is not continuous at the point ``x=15/11``.)
|
||||
|
||||
@ -17,7 +17,7 @@ const frontmatter = (
|
||||
description = "Calculus with Julia: Limits",
|
||||
tags = ["CalculusWithJulia", "limits", "limits"],
|
||||
);
|
||||
const fig_size=(400, 300)
|
||||
fig_size=(800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
@ -287,8 +287,9 @@ This progression can be seen to be increasing. Cauchy, in his treatise, can see
|
||||
```math
|
||||
\begin{align*}
|
||||
(1 + \frac{1}{m})^n &= 1 + \frac{1}{1} + \frac{1}{1\cdot 2}(1 = \frac{1}{m}) + \\
|
||||
& \frac{1}{1\cdot 2\cdot 3}(1 - \frac{1}{m})(1 - \frac{2}{m}) + \cdots +
|
||||
& \frac{1}{1 \cdot 2 \cdot \cdots \cdot m}(1 - \frac{1}{m}) \cdot \cdots \cdot (1 - \frac{m-1}{m}).
|
||||
& \frac{1}{1\cdot 2\cdot 3}(1 - \frac{1}{m})(1 - \frac{2}{m}) + \cdots \\
|
||||
&+
|
||||
\frac{1}{1 \cdot 2 \cdot \cdots \cdot m}(1 - \frac{1}{m}) \cdot \cdots \cdot (1 - \frac{m-1}{m}).
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
@ -1088,8 +1089,8 @@ plot(f, 0,2)
|
||||
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 1/4
|
||||
numericq(ans, 1e-1)
|
||||
answ = 1/4
|
||||
numericq(answ, 1e-1)
|
||||
```
|
||||
|
||||
|
||||
@ -1158,36 +1159,38 @@ numericq(val, 1e-2)
|
||||
Select the graph for which there is no limit at ``a``.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
p1 = plot(;axis=nothing, legend=false)
|
||||
title!(p1, "(a)")
|
||||
plot!(p1, x -> x^2, 0, 2, color=:black)
|
||||
plot!(p1, zero, linestyle=:dash)
|
||||
annotate!(p1,[(1,0,"a")])
|
||||
let
|
||||
p1 = plot(;axis=nothing, legend=false)
|
||||
title!(p1, "(a)")
|
||||
plot!(p1, x -> x^2, 0, 2, color=:black)
|
||||
plot!(p1, zero, linestyle=:dash)
|
||||
annotate!(p1,[(1,0,"a")])
|
||||
|
||||
p2 = plot(;axis=nothing, legend=false)
|
||||
title!(p2, "(b)")
|
||||
plot!(p2, x -> 1/(1-x), 0, .95, color=:black)
|
||||
plot!(p2, x-> -1/(1-x), 1.05, 2, color=:black)
|
||||
plot!(p2, zero, linestyle=:dash)
|
||||
annotate!(p2,[(1,0,"a")])
|
||||
p2 = plot(;axis=nothing, legend=false)
|
||||
title!(p2, "(b)")
|
||||
plot!(p2, x -> 1/(1-x), 0, .95, color=:black)
|
||||
plot!(p2, x-> -1/(1-x), 1.05, 2, color=:black)
|
||||
plot!(p2, zero, linestyle=:dash)
|
||||
annotate!(p2,[(1,0,"a")])
|
||||
|
||||
p3 = plot(;axis=nothing, legend=false)
|
||||
title!(p3, "(c)")
|
||||
plot!(p3, sinpi, 0, 2, color=:black)
|
||||
plot!(p3, zero, linestyle=:dash)
|
||||
annotate!(p3,[(1,0,"a")])
|
||||
p3 = plot(;axis=nothing, legend=false)
|
||||
title!(p3, "(c)")
|
||||
plot!(p3, sinpi, 0, 2, color=:black)
|
||||
plot!(p3, zero, linestyle=:dash)
|
||||
annotate!(p3,[(1,0,"a")])
|
||||
|
||||
p4 = plot(;axis=nothing, legend=false)
|
||||
title!(p4, "(d)")
|
||||
plot!(p4, x -> x^x, 0, 2, color=:black)
|
||||
plot!(p4, zero, linestyle=:dash)
|
||||
annotate!(p4,[(1,0,"a")])
|
||||
p4 = plot(;axis=nothing, legend=false)
|
||||
title!(p4, "(d)")
|
||||
plot!(p4, x -> x^x, 0, 2, color=:black)
|
||||
plot!(p4, zero, linestyle=:dash)
|
||||
annotate!(p4,[(1,0,"a")])
|
||||
|
||||
l = @layout[a b; c d]
|
||||
p = plot(p1, p2, p3, p4, layout=l)
|
||||
imgfile = tempname() * ".png"
|
||||
savefig(p, imgfile)
|
||||
hotspotq(imgfile, (1/2,1), (1/2,1))
|
||||
l = @layout[a b; c d]
|
||||
p = plot(p1, p2, p3, p4, layout=l)
|
||||
imgfile = tempname() * ".png"
|
||||
savefig(p, imgfile)
|
||||
hotspotq(imgfile, (1/2,1), (1/2,1))
|
||||
end
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1209,8 +1212,8 @@ What is $L$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``0``", "``1``", "``e^x``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1237,8 +1240,8 @@ Using the last result, what is the value of $L$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``\\cos(x)``", "``\\sin(x)``", "``1``", "``0``", "``\\sin(h)/h``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1309,8 +1312,8 @@ the fact that $x$ is measured in radians. Try to find this limit:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [q"0", q"1", q"pi/180", q"180/pi"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1318,8 +1321,8 @@ What is the limit `limit(sinpi(x)/x, x => 0)`?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [q"0", q"1", q"pi", q"1/pi"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question: limit properties
|
||||
@ -1388,8 +1391,8 @@ choices = [
|
||||
"Yes, the value is `-11.5123`",
|
||||
"No, the value heads to negative infinity"
|
||||
];
|
||||
ans = 3;
|
||||
radioq(choices, ans)
|
||||
answ = 3;
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1433,8 +1436,8 @@ What is `limit(ex, x => 0)`?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``e^{km}``", "``e^{k/m}``", "``k/m``", "``m/k``", "``0``"]
|
||||
answer = 1
|
||||
radioq(choices, answer)
|
||||
answwer = 1
|
||||
radioq(choices, answwer)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1511,8 +1514,8 @@ between both $g$ and $h$, so must to have a limit of $0$.
|
||||
""",
|
||||
L"The functions $g$ and $h$ squeeze each other as $g(x) > h(x)$",
|
||||
L"The function $f$ has no limit - it oscillates too much near $0$"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
(The [Wikipedia](https://en.wikipedia.org/wiki/Squeeze_theorem) entry for the squeeze theorem has this unverified, but colorful detail:
|
||||
|
||||
@ -149,11 +149,9 @@ limit(f(x), x=>0, dir="+"), limit(f(x), x=>0, dir="-")
|
||||
```
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
alert("""
|
||||
That means the mathematical limit need not exist when `SymPy`'s `limit` returns an answer, as `SymPy` is only carrying out a one sided limit. Explicitly passing `dir="+-"` or checking that both `limit(ex, x=>c)` and `limit(ex, x=>c, dir="-")` are equal would be needed to confirm a limit exists mathematically.
|
||||
""")
|
||||
```
|
||||
!!! warning
|
||||
That means the mathematical limit need not exist when `SymPy`'s `limit` returns an answer, as `SymPy` is only carrying out a one sided limit. Explicitly passing `dir="+-"` or checking that both `limit(ex, x=>c)` and `limit(ex, x=>c, dir="-")` are equal would be needed to confirm a limit exists mathematically.
|
||||
|
||||
|
||||
The relation between the two concepts is that a function has a limit at $c$ if
|
||||
an only if the left and right limits exist and are equal. This
|
||||
@ -623,7 +621,6 @@ The last equality follows, as the function ``x`` dominates the function ``\ln(x)
|
||||
|
||||
## Questions
|
||||
|
||||
|
||||
###### Question
|
||||
|
||||
Select the graph for which the limit at ``a`` is infinite.
|
||||
@ -761,8 +758,8 @@ Find $\lim_{x \rightarrow 2+} (x-3)/(x-2)$.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices=["``L=-\\infty``", "``L=-1``", "``L=0``", "``L=\\infty``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Find $\lim_{x \rightarrow -3-} (x-3)/(x+3)$.
|
||||
@ -771,8 +768,8 @@ Find $\lim_{x \rightarrow -3-} (x-3)/(x+3)$.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices=["``L=-\\infty``", "``L=-1``", "``L=0``", "``L=\\infty``"]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -861,8 +858,8 @@ choices=["The limit does exist - it is any number from -1 to 1",
|
||||
"Err, the limit does exists and is 1",
|
||||
"The function oscillates too much and its y values do not get close to any one value",
|
||||
"Any function that oscillates does not have a limit."]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -883,8 +880,8 @@ Consider different values of $k$ to see if this limit depends on $k$ or not. Wha
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``1``", "``k``", "``\\log(k)``", "The limit does not exist"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -908,8 +905,8 @@ Consider different values of $k$ to see if the limit depends on $k$ or not. What
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``1``", "``k``", "``\\log(k)``", "The limit does not exist"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -929,8 +926,8 @@ choices=[
|
||||
"the first, second and third ones",
|
||||
"the first, second, third, and fourth ones",
|
||||
"all of them"]
|
||||
ans = 5
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 5
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -947,8 +944,8 @@ L"We can talk about the limit at $\infty$ of $f(x) - mx$ being $b$",
|
||||
L"We can say $f(x) - (mx+b)$ has a horizontal asymptote $y=0$",
|
||||
L"We can say $f(x) - mx$ has a horizontal asymptote $y=b$",
|
||||
"Any of the above"]
|
||||
ans = 5
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 5
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -976,6 +973,6 @@ choices = [L" $f(x)$ has a limit of $1$ as $x \rightarrow 0$",
|
||||
L" $f(x)$ has a limit of $-1$ as $x \rightarrow 0$",
|
||||
L" $f(x)$ does not have a limit as $x \rightarrow 0$"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -28,7 +28,6 @@ Clicking the launch link above will open a web page which provides a
|
||||
blank notebook, save for a package used by these notes. However,
|
||||
`Binder` is nowhere near as reliable as a local installation.
|
||||
|
||||
These notes use `Pluto` notebooks. The "Edit or run this notebook" button allows each notebook to be run through binder. However, it can take several minutes for binder to show any given notebook. (Binder works best when no or few external packages are used.)
|
||||
|
||||
|
||||
## Installing Julia locally
|
||||
@ -86,14 +85,16 @@ coloring. For example:
|
||||
2 + 2
|
||||
```
|
||||
|
||||
While many prefer a command line for interacting with `Julia`, when learning a notebook interfaces is suggested. (An IDE like [Julia for Visual Studio Code](https://www.julia-vscode.org/) might be preferred for experienced programmers). In [Julia interfaces](./julia_interfaces.html), we describe two different notebook interfaces that are available through add-on packages. (These notes use `Pluto`, one of the two.)
|
||||
While many prefer a command line for interacting with `Julia`, when learning a notebook interfaces is suggested. (An IDE like [Julia for Visual Studio Code](https://www.julia-vscode.org/) might be preferred for experienced programmers). In [Julia interfaces](./julia_interfaces.html), we describe two different notebook interfaces that are available through add-on packages.
|
||||
|
||||
|
||||
|
||||
## Add-on packages
|
||||
|
||||
`Julia` has well over a 1000 external, add-on packages that enhance the
|
||||
offerings of base `Julia`. We refer to one, `CalculusWithJulia`, that is designed to accompany these notes. [Installation notes](./calculus_with_julia.html) are available.
|
||||
`Julia` is well on its way towards 10,000 external add-on packages
|
||||
that enhance the offerings of base `Julia`. We refer to one,
|
||||
`CalculusWithJulia`, that is designed to accompany these
|
||||
notes. [Installation notes](./calculus_with_julia.html) are available.
|
||||
|
||||
|
||||
|
||||
|
||||
@ -11,33 +11,12 @@ Julia can be used through the internet for free using the [mybinder.org](https:/
|
||||
Just click on the `CalcululsWithJulia.ipynb` file after launching Binder by clicking on the badge. Binder provides the Jupyter interface.
|
||||
|
||||
|
||||
These notes are written as Pluto HTML pages. Pluto is a notebook like alternative to Jupyter which is designed for interactive Julia usage using a *reactive model*. The HTML pages
|
||||
an be downloaded and run as notebooks within Pluto. (They can also be run through binder, but that will be a disappointing experience due to limitations imposed by binder.)
|
||||
Pluto will automatically handle the package management for add-on packages, though `Pluto` itself must be installed. In a terminal session, the following commands will install `Pluto`:
|
||||
|
||||
```julia; eval=false
|
||||
import Pkg
|
||||
Pkg.add("Pluto")
|
||||
```
|
||||
|
||||
Installation happens once. Then each new *session*, `Pluto` must be loaded and run:
|
||||
|
||||
```julia; eval=false
|
||||
using Pluto
|
||||
Pluto.run()
|
||||
```
|
||||
|
||||
`Pluto` notebooks run in a web browser, the above command will open a landing page in the default browser.
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Here are some `Julia` usages to create calculus objects.
|
||||
|
||||
The `Julia` packages loaded below are all loaded when the `CalculusWithJulia` package is loaded.
|
||||
@ -84,8 +63,6 @@ f(x) = exp(x) * 2x
|
||||
```
|
||||
|
||||
|
||||
!!! note
|
||||
We see in this notebook the use of `let` blocks, which is not typical with `Pluto`. As `Pluto` is reactive -- meaning changes in a variable propagate automatically to variables which reference the changed one -- a variable can only be used *once* per notebook at the top level. The `let` block, like a function body, introduces a separate scope for the binding so `Pluto` doesn't incorporate the binding in its reactive model. This is necessary as we have more than one function named `f`. This is unlike `begin` blocks, which are quite typical in `Pluto`. The `begin` blocks allow one or more commands to occur in a cell, as the design of `Pluto` is one object per cell.
|
||||
|
||||
* multi-statement functions are defined with the `function` keyword. The `end` statement ends the definition. The last evaluated command is returned. There is no need for explicit `return` statement, though it can be useful for control flow.
|
||||
|
||||
|
||||
6
CwJ/misc/using-pluto.jmd
Normal file
@ -0,0 +1,6 @@
|
||||
# Using Pluto
|
||||
|
||||
|
||||
|
||||
!!! note
|
||||
We see in this notebook the use of `let` blocks, which is not typical with `Pluto`. As `Pluto` is reactive -- meaning changes in a variable propagate automatically to variables which reference the changed one -- a variable can only be used *once* per notebook at the top level. The `let` block, like a function body, introduces a separate scope for the binding so `Pluto` doesn't incorporate the binding in its reactive model. This is necessary as we have more than one function named `f`. This is unlike `begin` blocks, which are quite typical in `Pluto`. The `begin` blocks allow one or more commands to occur in a cell, as the design of `Pluto` is one object per cell.
|
||||
@ -77,6 +77,7 @@ on how it is being called. Within `Pluto`, a message about
|
||||
this will be noted.
|
||||
|
||||
|
||||
|
||||
The basic arithmetic operations on a calculator are "+", "-", "×",
|
||||
"÷", and "$xʸ$". These have parallels in `Julia` through the *binary*
|
||||
operators: `+`, `-`, `*`, `/`, and `^`:
|
||||
@ -320,23 +321,21 @@ To emphasize, this is not the same as the value without the parentheses:
|
||||
1 + 2 / 3 + 4
|
||||
```
|
||||
|
||||
```julia; echo=false;
|
||||
alert(L"""
|
||||
!!! warning
|
||||
The viniculum also indicates grouping when used with the
|
||||
square root (the top bar), and complex conjugation. That usage is
|
||||
often clear enough, but the usage of the viniculum in division
|
||||
often leads to confusion. The example above is one where the
|
||||
parentheses are often, erroneously, omitted. However, more
|
||||
confusion can arise when there is more than one vinicula. An
|
||||
expression such as $a/b/c$ written inline has no confusion, it is:
|
||||
$(a/b) / c$ as left association is used; but when written with a
|
||||
pair of vinicula there is often the typographical convention of a
|
||||
slightly longer vinicula to indicate which is to be considered
|
||||
first. In the absence of that, then top to bottom association is
|
||||
often implied.
|
||||
|
||||
The viniculum also indicates grouping when used with the square root
|
||||
(the top bar), and complex conjugation. That usage is often clear
|
||||
enough, but the usage of the viniculum in division often leads to
|
||||
confusion. The example above is one where the parentheses are often,
|
||||
erroneously, omitted. However, more confusion can arise when there is
|
||||
more than one vinicula. An expression such as $a/b/c$ written inline
|
||||
has no confusion, it is: $(a/b) / c$ as left association is used; but
|
||||
when written with a pair of vinicula there is often the typographical
|
||||
convention of a slightly longer vinicula to indicate which is to
|
||||
be considered first. In the absence of that, then top to bottom association is
|
||||
often implied.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
### Infix, postfix, and prefix notation
|
||||
|
||||
@ -356,13 +355,9 @@ unfamiliar with. These mirror the familiar notation from most math
|
||||
texts.
|
||||
|
||||
|
||||
```julia; echo=false;
|
||||
note("""
|
||||
!!! note
|
||||
In `Julia` many infix operations can be done using a prefix manner. For example `14 + 2` can also be evaluated by `+(14,2)`. There are very few *postfix* operations, though in these notes we will overload one, the `'` operation, to indicate a derivative.
|
||||
|
||||
In `Julia` many infix operations can be done using a prefix manner. For example `14 + 2` can also be evaluated by `+(14,2)`. There are very few *postfix* operations, though in these notes we will overload one, the `'` operation, to indicate a derivative.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
## Constants
|
||||
|
||||
@ -378,11 +373,9 @@ Whereas, `e` is is not simply the character `e`, but *rather* a [Unicode](../uni
|
||||
ℯ
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
However, when the accompanying package, `CalculusWithJulia`, is loaded, the character `e` will refer to a floating point approximation to the Euler constant .
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
However, when the accompanying package, `CalculusWithJulia`, is loaded, the character `e` will refer to a floating point approximation to the Euler constant .
|
||||
|
||||
|
||||
In the sequel, we will just use `e` for this constant (though more commonly the `exp` function), with the reminder that base `Julia` alone does not reserve this symbol.
|
||||
|
||||
@ -393,10 +386,12 @@ Mathematically these are irrational values with decimal expansions that do not r
|
||||
```
|
||||
|
||||
|
||||
```julia; echo=false;
|
||||
alert("""In most cases. There are occasional (basically rare) spots where using `pi` by itself causes an eror where `1*pi` will not. The reason is `1*pi` will create a floating point value from the irrational object, `pi`.
|
||||
""")
|
||||
```
|
||||
!!! warning
|
||||
In most cases. There are occasional (basically rare) spots
|
||||
where using `pi` by itself causes an eror where `1*pi` will
|
||||
not. The reason is `1*pi` will create a floating point value from
|
||||
the irrational object, `pi`.
|
||||
|
||||
|
||||
|
||||
### Numeric literals
|
||||
@ -504,19 +499,14 @@ exp(2), log(10), sqrt(100), 10^(1/2)
|
||||
```
|
||||
|
||||
|
||||
!!! note
|
||||
Parentheses have many roles. We've just seen that parentheses may be
|
||||
used for grouping, and now we see they are used to indicate a function
|
||||
is being called. These are familiar from their parallel usage in
|
||||
traditional math notation. In `Julia`, a third usage is common, the
|
||||
making of a "tuple," or a container of different objects, for example
|
||||
`(1, sqrt(2), pi)`. In these notes, the output of multiple commands separated by commas is a printed tuple.
|
||||
|
||||
```julia; echo=false;
|
||||
note("""
|
||||
|
||||
Parentheses have many roles. We've just seen that parentheses may be
|
||||
used for grouping, and now we see they are used to indicate a function
|
||||
is being called. These are familiar from their parallel usage in
|
||||
traditional math notation. In `Julia`, a third usage is common, the
|
||||
making of a "tuple," or a container of different objects, for example
|
||||
`(1, sqrt(2), pi)`. In these notes, the output of multiple commands separated by commas is a printed tuple.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -621,21 +611,17 @@ exact, can represent much bigger values and are exact for a reasonably
|
||||
wide range of integer values.)
|
||||
|
||||
|
||||
```julia; echo=false;
|
||||
alert("""
|
||||
!!! warning
|
||||
In a turnaround from a classic blues song, we can think of
|
||||
`Julia` as built for speed, not for comfort. All of these errors
|
||||
above could be worked around so that the end user doesn't see
|
||||
them. However, this would require slowing things down, either
|
||||
through checking of operations or allowing different types of
|
||||
outputs for similar type of inputs. These are tradeoffs that are
|
||||
not made for performance reasons. For the most part, the tradeoffs
|
||||
don't get in the way, but learning where to be careful takes some
|
||||
time. Error messages often suggest a proper alternative.
|
||||
|
||||
In a turnaround from a classic blues song, we can think of `Julia` as
|
||||
built for speed, not for comfort. All of these errors above could be
|
||||
worked around so that the end user doesn't see them. However, this
|
||||
would require slowing things down, either through checking of
|
||||
operations or allowing different types of outputs for similar type of
|
||||
inputs. These are tradeoffs that are not made for performance
|
||||
reasons. For the most part, the tradeoffs don't get in the way, but
|
||||
learning where to be careful takes some time. Error messages
|
||||
often suggest a proper alternative.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
@ -798,8 +784,8 @@ choices = [
|
||||
q"(3 - 2)/ 4 - 1",
|
||||
q"3 - 2 / (4 - 1)",
|
||||
q"(3 - 2) / (4 - 1)"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -818,8 +804,8 @@ choices = [
|
||||
q"3 * 2 / 4",
|
||||
q"(3 * 2) / 4"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -838,8 +824,8 @@ choices = [
|
||||
q"2 ^ 4 - 2",
|
||||
q"(2 ^ 4) - 2",
|
||||
q"2 ^ (4 - 2)"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -863,8 +849,8 @@ choices = [
|
||||
q"1 / (2 / 3 / 4 / 5 / 6)",
|
||||
q"1 / 2 * 3 / 4 * 5 / 6",
|
||||
q"1 /(2 * 3 * 4 * 5 * 6)"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -879,8 +865,8 @@ q"2 - 3 - 4",
|
||||
q"(2 - 3) - 4",
|
||||
q"2 - (3 - 4)"
|
||||
];
|
||||
ans = 3;
|
||||
radioq(choices, ans)
|
||||
answ = 3;
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -895,8 +881,8 @@ q"2 - 3 * 4",
|
||||
q"(2 - 3) * 4",
|
||||
q"2 - (3 * 4)"
|
||||
];
|
||||
ans = 2;
|
||||
radioq(choices, ans)
|
||||
answ = 2;
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -912,8 +898,8 @@ q"-1^2",
|
||||
q"(-1)^2",
|
||||
q"-(1^2)"
|
||||
];
|
||||
ans = 2;
|
||||
radioq(choices, ans)
|
||||
answ = 2;
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -989,8 +975,8 @@ choices = [
|
||||
raw"``e^{\pi}``",
|
||||
raw"``\pi^{e}``"
|
||||
];
|
||||
ans = exp(pi) - pi^exp(1) > 0 ? 1 : 2;
|
||||
radioq(choices, ans)
|
||||
answ = exp(pi) - pi^exp(1) > 0 ? 1 : 2;
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1002,8 +988,8 @@ What is the value of $\pi - (x - \sin(x)/\cos(x))$ when $x=3$?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
x = 3;
|
||||
ans = x - sin(x)/cos(x);
|
||||
numericq(pi - ans)
|
||||
answ = x - sin(x)/cos(x);
|
||||
numericq(pi - answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1022,8 +1008,8 @@ Will `-2^2` produce `4` (which is a unary `-` evaluated *before* `^`) or `-4` (w
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = [q"4", q"-4"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1057,6 +1043,6 @@ choices = [
|
||||
"The precedence of numeric literal coefficients used for implicit multiplication is higher than other binary operators such as multiplication (`*`), and division (`/`, `\\`, and `//`)",
|
||||
"Of course it is correct."
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -165,11 +165,9 @@ That would be an enormous growth. Don't worry: "Exponential growth
|
||||
cannot continue indefinitely, however, because the medium is soon
|
||||
depleted of nutrients and enriched with wastes."
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The value of `2^n` and `2.0^n` is different in `Julia`. The former remains an integer and is subject to integer overflow for `n > 62`. As used above, `2^(n/6)` will not overflow for larger `n`, as when the exponent is a floating point value, the base is promoted to a floating point value.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The value of `2^n` and `2.0^n` is different in `Julia`. The former remains an integer and is subject to integer overflow for `n > 62`. As used above, `2^(n/6)` will not overflow for larger `n`, as when the exponent is a floating point value, the base is promoted to a floating point value.
|
||||
|
||||
|
||||
##### Example
|
||||
|
||||
@ -366,11 +364,9 @@ If $1/10$ of the original carbon ``14`` remains, how old is the item? This amoun
|
||||
-5730 * log2(1/10)
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
(Historically) Libby and James Arnold proceeded to test the radiocarbon dating theory by analyzing samples with known ages. For example, two samples taken from the tombs of two Egyptian kings, Zoser and Sneferu, independently dated to ``2625`` BC plus or minus ``75`` years, were dated by radiocarbon measurement to an average of ``2800`` BC plus or minus ``250`` years. These results were published in Science in ``1949``. Within ``11`` years of their announcement, more than ``20`` radiocarbon dating laboratories had been set up worldwide. Source: [Wikipedia](http://tinyurl.com/p5msnh6).
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
(Historically) Libby and James Arnold proceeded to test the radiocarbon dating theory by analyzing samples with known ages. For example, two samples taken from the tombs of two Egyptian kings, Zoser and Sneferu, independently dated to ``2625`` BC plus or minus ``75`` years, were dated by radiocarbon measurement to an average of ``2800`` BC plus or minus ``250`` years. These results were published in Science in ``1949``. Within ``11`` years of their announcement, more than ``20`` radiocarbon dating laboratories had been set up worldwide. Source: [Wikipedia](http://tinyurl.com/p5msnh6).
|
||||
|
||||
|
||||
### Properties of logarithms
|
||||
|
||||
@ -503,8 +499,8 @@ Which is bigger $e^2$ or $2^e$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``e^2``", "``2^e``"]
|
||||
ans = e^2 - 2^e > 0 ? 1 : 2
|
||||
radioq(choices, ans)
|
||||
answ = e^2 - 2^e > 0 ? 1 : 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -514,8 +510,8 @@ Which is bigger $\log_8(9)$ or $\log_9(10)$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [raw"``\log_8(9)``", raw"``\log_9(10)``"]
|
||||
ans = log(8,9) > log(9,10) ? 1 : 2
|
||||
radioq(choices, ans)
|
||||
answ = log(8,9) > log(9,10) ? 1 : 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -529,8 +525,8 @@ raw"``\frac{\log(2)\log(3)}{\log(5)\log(4)}``",
|
||||
raw"``2/5``",
|
||||
raw"``\frac{\log(5)\log(4)}{\log(3)\log(2)}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -538,8 +534,8 @@ radioq(choices, ans)
|
||||
Does $12$ satisfy $\log_2(x) + \log_3(x) = \log_4(x)$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = log(2,12) + log(3,12) == log(4, 12)
|
||||
yesnoq(ans)
|
||||
answ = log(2,12) + log(3,12) == log(4, 12)
|
||||
yesnoq(answ)
|
||||
```
|
||||
|
||||
|
||||
@ -563,8 +559,8 @@ for each?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``1000`` times", "``100`` times", "``10`` times", "the same"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -600,8 +596,8 @@ choices = [
|
||||
raw"``x \geq 1 + \log(x)``",
|
||||
raw"``x \leq 1 + \log(x)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -623,8 +619,8 @@ choices = [
|
||||
raw"``\log(1-x) \geq -x - x^2/2``",
|
||||
raw"``\log(1-x) \leq -x - x^2/2``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -634,8 +630,8 @@ reciprocal property of exponents, $a^{-x} = (1/a)^x$, is at play here.)
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``-y``", "``1/y``", "``-1/y``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Based on this, the graph of $\log_{1/a}(x)$ is the graph of
|
||||
@ -647,8 +643,8 @@ L"Flipped over the $x$ axis",
|
||||
L"Flipped over the $y$ axis",
|
||||
L"Flipped over the line $y=x$"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -662,8 +658,8 @@ choices = [
|
||||
raw"``a^{y-x}``",
|
||||
raw"``a^{y-x} \cdot (a^x - 1)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Using $a > 1$ we have:
|
||||
@ -674,8 +670,8 @@ choices = [
|
||||
L"as $a^x > 1$, $a^y > a^x$",
|
||||
"``a^{y-x} > 0``"
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
If $a < 1$ then:
|
||||
@ -686,6 +682,6 @@ L"as $a^{y-x} < 1$ as $y-x > 0$, $a^y < a^x$",
|
||||
L"as $a^x < 1$, $a^y < a^x$",
|
||||
"``a^{y-x} < 0``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -54,10 +54,8 @@ possible. The function $h(x)$ would have range
|
||||
$[0,\infty)$. The $s(x)$ function is either $-1$ or $1$, so only has two possible values in its range. What about $g(x)$? It is a parabola that opens upward, so any $y$ values below the $y$ value of its vertex will not appear in the range. In this case, the symmetry indicates that the vertex will be at $(1/2, -1/4)$, so the range is $[-1/4, \infty)$.
|
||||
|
||||
|
||||
```julia;echo=false;
|
||||
note("""
|
||||
|
||||
**Thanks to Euler (1707-1783):** The formal idea of a function is a relatively modern concept in mathematics. According to [Dunham](http://www.maa.org/sites/default/files/pdf/upload_library/22/Ford/dunham1.pdf),
|
||||
!!! note
|
||||
**Thanks to Euler (1707-1783):** The formal idea of a function is a relatively modern concept in mathematics. According to [Dunham](http://www.maa.org/sites/default/files/pdf/upload_library/22/Ford/dunham1.pdf),
|
||||
Euler defined a function as an "analytic expression composed in any way
|
||||
whatsoever of the variable quantity and numbers or constant
|
||||
quantities." He goes on to indicate that as Euler matured, so did
|
||||
@ -66,8 +64,6 @@ note("""
|
||||
“analytic expression.” He finishes by saying: "It is fair to say
|
||||
that we now study functions in analysis because of him."
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
We will see that defining functions within `Julia` can be as simple a concept as Euler started with, but that the more abstract concept has a great advantage that is exploited in the design of the language.
|
||||
|
||||
@ -92,28 +88,24 @@ f(pi), g(2), h(4)
|
||||
For typical cases like the three above, there isn't really much new to learn.
|
||||
|
||||
|
||||
```julia;echo=false;
|
||||
note("""
|
||||
!!! note
|
||||
The equals sign in `Julia` always indicates either an assignment or a
|
||||
mutation of the object on the left side. The definition of a function
|
||||
above is an *assignment*, in that a function is added (or modified) in
|
||||
a table holding the methods associated with the function's name.
|
||||
|
||||
The equals sign in `Julia` always indicates either an assignment or a
|
||||
mutation of the object on the left side. The definition of a function
|
||||
above is an *assignment*, in that a function is added (or modified) in
|
||||
a table holding the methods associated with the function's name.
|
||||
The equals sign restricts the expressions available on the *left*-hand
|
||||
side to a) a variable name, for assignment; b) mutating an object at an index,
|
||||
as in `xs[1]`; c) mutating a property of a stuct; or d) a function assignment
|
||||
following this form `function_name(args...)`.
|
||||
|
||||
The equals sign restricts the expressions available on the *left*-hand
|
||||
side to a) a variable name, for assignment; b) mutating an object at an index,
|
||||
as in `xs[1]`; c) mutating a property of a stuct; or d) a function assignment
|
||||
following this form `function_name(args...)`.
|
||||
Whereas function
|
||||
definitions and usage in `Julia` mirrors standard math notation;
|
||||
equations in math are not so mirrored in `Julia`. In mathematical
|
||||
equations, the left-hand of an equation is typically a complicated
|
||||
algebraic expression. Not so with `Julia`, where the left hand side of
|
||||
the equals sign is prescribed and quite limited.
|
||||
|
||||
Whereas function
|
||||
definitions and usage in `Julia` mirrors standard math notation;
|
||||
equations in math are not so mirrored in `Julia`. In mathematical
|
||||
equations, the left-hand of an equation is typically a complicated
|
||||
algebraic expression. Not so with `Julia`, where the left hand side of
|
||||
the equals sign is prescribed and quite limited.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
### The domain of a function
|
||||
|
||||
@ -244,17 +236,12 @@ Or similarly, a function to represent a cell phone plan where the first ``500``
|
||||
cellplan(x) = x < 500 ? 20.0 : 20.0 + 0.05 * (x-500)
|
||||
```
|
||||
|
||||
```julia;echo=false;
|
||||
alert("""
|
||||
|
||||
Type stability. These last two definitions used `10.0` and `20.0`
|
||||
instead of the integers `10` and `20` for the answer. Why the extra
|
||||
typing? When `Julia` can predict the type of the output from the type
|
||||
of inputs, it can be more efficient. So when possible, we help out and
|
||||
ensure the output is always the same type.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! warning
|
||||
Type stability. These last two definitions used `10.0` and `20.0`
|
||||
instead of the integers `10` and `20` for the answer. Why the extra
|
||||
typing? When `Julia` can predict the type of the output from the type
|
||||
of inputs, it can be more efficient. So when possible, we help out and
|
||||
ensure the output is always the same type.
|
||||
|
||||
##### Example
|
||||
|
||||
@ -303,11 +290,9 @@ end
|
||||
|
||||
The line `return x^2`, could have just been `x^2` as it is the last (and) only line evaluated.
|
||||
|
||||
```julia;echo=false;
|
||||
note("""
|
||||
The `return` keyword is not a function, so is not called with parentheses. An emtpy `return` statement will return a value of `nothing`.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The `return` keyword is not a function, so is not called with parentheses. An emtpy `return` statement will return a value of `nothing`.
|
||||
|
||||
|
||||
|
||||
##### Example
|
||||
@ -602,11 +587,9 @@ just uses the change-of-base formula for logarithms.
|
||||
|
||||
But not so fast, on the left side is a function with two arguments and on the right side the functions have one argument - yet they share the same name. How does `Julia` know which to use? `Julia` uses the number, order, and *type* of the positional arguments passed to a function to determine which function definition to use. This is technically known as [multiple dispatch](http://en.wikipedia.org/wiki/Multiple_dispatch) or **polymorphism**. As a feature of the language, it can be used to greatly simplify the number of functions the user must learn. The basic idea is that many functions are "generic" in that they have methods which will work differently in different scenarios.
|
||||
|
||||
```julia;echo=false;
|
||||
alert("""
|
||||
Multiple dispatch is very common in mathematics. For example, we learn different ways to add: integers (fingers, carrying), real numbers (align the decimal points), rational numbers (common denominators), complex numbers (add components), vectors (add components), polynomials (combine like monomials), ... yet we just use the same `+` notation for each operation. The concepts are related, the details different.
|
||||
""")
|
||||
```
|
||||
!!! warning
|
||||
Multiple dispatch is very common in mathematics. For example, we learn different ways to add: integers (fingers, carrying), real numbers (align the decimal points), rational numbers (common denominators), complex numbers (add components), vectors (add components), polynomials (combine like monomials), ... yet we just use the same `+` notation for each operation. The concepts are related, the details different.
|
||||
|
||||
|
||||
`Julia` is similarly structured. `Julia` terminology would be to call the operation "`+`" a *generic function* and the different implementations *methods* of "`+`". This allows the user to just need to know a smaller collection of generic concepts yet still have the power of detail-specific implementations. To see how many different methods are defined in the base `Julia` language for the `+` operator, we can use the command `methods(+)`. As there are so many ($\approx 200$) and that number is growing, we illustrate how many different logarithm methods are implemented for "numbers:"
|
||||
|
||||
@ -720,17 +703,15 @@ creates a function, this function is returned by `shift_right`.
|
||||
So we could have done something more complicated like:
|
||||
|
||||
```julia;
|
||||
p(x) = x^2 - 2x
|
||||
l = shift_right(p, c=3)
|
||||
f(x) = x^2 - 2x
|
||||
l = shift_right(f, c=3)
|
||||
```
|
||||
|
||||
Then `l` is a function that is derived from `p`.
|
||||
Then `l` is a function that is derived from `f`.
|
||||
|
||||
!!! note
|
||||
The value of `c` used when `l` is called is the one passed to `shift_right`. Functions like `l` that are returned by other functions also are called *closures*, as the context they are evaluated within includes the context of the function that constructs them.
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
The value of `c` used when `l` is called is the one passed to `shift_right`. Functions like `l` that are returned by other functions also are called *closures*, as the context they are evaluated within includes the context of the function that constructs them.
|
||||
""")
|
||||
```
|
||||
|
||||
Anonymous functions can be created with the `function` keyword, but we will use the "arrow" notation, `arg->body` to create them, The above, could have been defined as:
|
||||
|
||||
@ -741,32 +722,27 @@ shift_right_alt(f; c=0) = x -> f(x-c)
|
||||
When the `->` is seen a function is being created.
|
||||
|
||||
|
||||
```julia;echo=false;
|
||||
alert("""
|
||||
|
||||
Generic versus anonymous functions. Julia has two types of functions,
|
||||
generic ones, as defined by `f(x)=x^2` and anonymous ones, as defined
|
||||
by `x -> x^2`. One gotcha is that `Julia` does not like to use the
|
||||
same variable name for the two types. In general, Julia is a dynamic
|
||||
language, meaning variable names can be reused with different types
|
||||
of variables. But generic functions take more care, as when a new
|
||||
method is defined it gets added to a method table. So repurposing the
|
||||
name of a generic function for something else is not allowed (well, in `Pluto` it is.). Similarly,
|
||||
repurposing an already defined variable name for a generic function is
|
||||
not allowed. This comes up when we use functions that return functions
|
||||
as we have different styles that can be used: When we defined `l =
|
||||
shift_right(f, c=3)` the value of `l` is assigned an anonymous
|
||||
function. This binding can be reused to define other variables.
|
||||
However, we could have defined the function `l` through `l(x) =
|
||||
shift_right(f, c=3)(x)`, being explicit about what happens to the
|
||||
variable `x`. This would add a method to the generic function `l`. Meaning, we
|
||||
get an error if we tried to assign a variable to `l`, such as an
|
||||
expression like `l=3`. We generally employ the latter style, even though
|
||||
it involves a bit more typing, as we tend to stick to methods of generic
|
||||
functions for consistency.
|
||||
|
||||
""")
|
||||
```
|
||||
!!! warning
|
||||
Generic versus anonymous functions. Julia has two types of functions,
|
||||
generic ones, as defined by `f(x)=x^2` and anonymous ones, as defined
|
||||
by `x -> x^2`. One gotcha is that `Julia` does not like to use the
|
||||
same variable name for the two types. In general, Julia is a dynamic
|
||||
language, meaning variable names can be reused with different types
|
||||
of variables. But generic functions take more care, as when a new
|
||||
method is defined it gets added to a method table. So repurposing the
|
||||
name of a generic function for something else is not allowed. Similarly,
|
||||
repurposing an already defined variable name for a generic function is
|
||||
not allowed. This comes up when we use functions that return functions
|
||||
as we have different styles that can be used: When we defined `l =
|
||||
shift_right(f, c=3)` the value of `l` is assigned an anonymous
|
||||
function. This binding can be reused to define other variables.
|
||||
However, we could have defined the function `l` through `l(x) =
|
||||
shift_right(f, c=3)(x)`, being explicit about what happens to the
|
||||
variable `x`. This would add a method to the generic function `l`. Meaning, we
|
||||
get an error if we tried to assign a variable to `l`, such as an
|
||||
expression like `l=3`. We generally employ the latter style, even though
|
||||
it involves a bit more typing, as we tend to stick to methods of generic
|
||||
functions for consistency.
|
||||
|
||||
|
||||
##### Example: the secant line
|
||||
@ -863,8 +839,8 @@ choices = [
|
||||
"Domain is all non-negative numbers, range is all real numbers",
|
||||
"Domain is all non-negative numbers, range is all non-negative numbers"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
@ -879,8 +855,8 @@ L"Domain is all real numbers except $2$, range is all real numbers except $0$",
|
||||
L"Domain is all non-negative numbers except $0$, range is all real numbers except $2$",
|
||||
L"Domain is all non-negative numbers except $-2$, range is all non-negative numbers except $0$"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
##### Question
|
||||
@ -893,8 +869,8 @@ raw"``f(x) = 2^x``",
|
||||
raw"``f(x) = 1/x^2``",
|
||||
raw"``f(x) = |x|``",
|
||||
raw"``f(x) = \sqrt{x}``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -908,8 +884,8 @@ q"function f(x) = sin(x + pi/3)",
|
||||
q"f(x) = sin(x + pi/3)",
|
||||
q"f: x -> sin(x + pi/3)",
|
||||
q"f x = sin(x + pi/3)"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -923,8 +899,8 @@ q"f(x) := (1 + x^2)^(-1)",
|
||||
q"f[x] = (1 + x^2)^(-1)",
|
||||
q"def f(x): (1 + x^2)^(-1)"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1057,8 +1033,8 @@ Will the call `C(1, mu=70)` use a value of `70` for `mu`?
|
||||
```julia; hold=true;echo=false;
|
||||
choices = ["Yes, this will work just as it does for keyword arguments",
|
||||
"No, there will be an error that the function does not accept keyword arguments"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1077,8 +1053,8 @@ choices = [
|
||||
"If `x` is in `[a,b]` it returns `x`, otherwise it returns `NaN`",
|
||||
"`x` is the larger of the minimum of `x` and `a` and the value of `b`, aka `max(min(x,a),b)`"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1108,8 +1084,8 @@ L"You still get $0.649...$",
|
||||
"You get a `MethodError`, as `cos(pi/4)` is evaluated as a number and `∘` is not defined for functions and numbers",
|
||||
"You get a `generic` function, but this won't be callable. If tried, it will give an method error."
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1121,8 +1097,8 @@ choices = [
|
||||
"It is `0.6663667453928805`, the same as `cos(sin(1))`",
|
||||
"It is `0.5143952585235492`, the same as `sin(cos(1))`",
|
||||
"It gives an error"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1136,8 +1112,8 @@ fn(3)
|
||||
|
||||
```julia; hold=true;echo=false;
|
||||
choices = ["`true`","`false`"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -1160,8 +1136,8 @@ Repeat the secant method two more times to find a better approximation for $\sqr
|
||||
|
||||
```julia; hold=true;echo=false;
|
||||
choices = [q"4//3", q"7//5", q"58//41", q"816//577"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
How small is the value of $f(c)$ for this value?
|
||||
@ -1175,8 +1151,8 @@ How close is this answer to the true value of $\sqrt{2}$?
|
||||
|
||||
```julia; hold=true;echo=false;
|
||||
choices = [L"about $8$ parts in $100$", L"about $1$ parts in $100$", L"about $4$ parts in $10,000$", L"about $2$ parts in $1,000,000$"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
(Finding a good approximation to $\sqrt{2}$ would be helpful to builders, for example, as it could be used to verify the trueness of a square room, say.)
|
||||
@ -1190,8 +1166,8 @@ choices = ["Just use `f = h - g`",
|
||||
"Define `f(x) = h(x) - g(x)`",
|
||||
"Use `x -> h(x) - g(x)` when the difference is needed"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
@ -120,10 +120,9 @@ From this, we have the function $g(y) = (y-32) / (9/5)$ is the inverse function
|
||||
|
||||
*Usually* we use the name $f^{-1}$ for the inverse function of $f$, so this would be most often [seen](http://tinyurl.com/qypbueb) as $f^{-1}(x) = (x-32)/(9/5)$ or after simplification $f^{-1}(x) = (5/9) \cdot (x-32)$.
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""The use of a negative exponent on the function name is *easily* confused for the notation for a reciprocal when it is used on a mathematical *expression*. An example might be the notation $(1/x)^{-1}$. As this is an expression this would simplify to $x$ and not the inverse of the *function* $f(x)=1/x$ (which is $f^{-1}(x) = 1/x$).
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The use of a negative exponent on the function name is *easily* confused for the notation for a reciprocal when it is used on a mathematical *expression*. An example might be the notation $(1/x)^{-1}$. As this is an expression this would simplify to $x$ and not the inverse of the *function* $f(x)=1/x$ (which is $f^{-1}(x) = 1/x$).
|
||||
|
||||
|
||||
|
||||
##### Example
|
||||
@ -277,10 +276,9 @@ same scale, so that this type of line will look perpendicular.)
|
||||
|
||||
One consequence of this symmetry, is that if $f$ is strictly increasing, then so is its inverse.
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""In the above we used `cbrt(x)` and not `x^(1/3)`. The latter usage assumes that $x \geq 0$ as it isn't guaranteed that for all real exponents the answer will be a real number. The `cbrt` function knows there will always be a real answer and provides it.
|
||||
""")
|
||||
```
|
||||
|
||||
!!!note
|
||||
In the above we used `cbrt(x)` and not `x^(1/3)`. The latter usage assumes that $x \geq 0$ as it isn't guaranteed that for all real exponents the answer will be a real number. The `cbrt` function knows there will always be a real answer and provides it.
|
||||
|
||||
|
||||
### Lines
|
||||
@ -323,8 +321,8 @@ Is it possible that a function have two different inverses?
|
||||
```julia; hold=true; echo=false
|
||||
choices = [L"No, for all $x$ in the domain an an inverse, the value of any inverse will be the same, hence all inverse functions would be identical.",
|
||||
L"Yes, the function $f(x) = x^2, x \geq 0$ will have a different inverse than the same function $f(x) = x^2, x \leq 0$"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -335,8 +333,8 @@ A function takes a value $x$ adds $1$, divides by $2$, and then subtracts $1$. I
|
||||
choices = [L"Yes, the function is the linear function $f(x)=(x+1)/2 + 1$ and so is monotonic.",
|
||||
L"No, the function is $1$ then $2$ then $1$, but not \"one-to-one\""
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -347,8 +345,8 @@ Is the function $f(x) = x^5 - x - 1$ one-to-one?
|
||||
choices=[L"Yes, a graph over $(-100, 100)$ will show this.",
|
||||
L"No, a graph over $(-2,2)$ will show this."
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -396,16 +394,16 @@ What is $g(x) = (f(x))^{-1}$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``g(x) = x``", "``g(x) = x^{-1}``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
What is $g(x) = f^{-1}(x)$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``g(x) = x``", "``g(x) = x^{-1}``"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -457,8 +455,8 @@ L"The function that multiplies by $2$, subtracts $1$ and then squares the value.
|
||||
L"The function that divides by $2$, adds $1$, and then takes the square root of the value.",
|
||||
L"The function that takes square of the value, then subtracts $1$, and finally multiplies by $2$."
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -509,8 +507,8 @@ choices = [
|
||||
"``f^{-1}(x) = (5y-4)^3``",
|
||||
"``f^{-1}(x) = 5/(x^3 + 4)``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -524,8 +522,8 @@ raw"``f^{-1}(x) = (x-e)^{1/\pi}``",
|
||||
raw"``f^{-1}(x) = (x-\pi)^{e}``",
|
||||
raw"``f^{-1}(x) = (x-e)^{\pi}``"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -536,8 +534,8 @@ choices = [
|
||||
raw"``[7, \infty)``",
|
||||
raw"``(-\infty, \infty)``",
|
||||
raw"``[0, \infty)``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -550,8 +548,8 @@ choices = [
|
||||
raw"``[7, \infty)``",
|
||||
raw"``(-\infty, \infty)``",
|
||||
raw"``[0, \infty)``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -620,8 +618,8 @@ choices = [
|
||||
L"As $f_4(f_3(f_2(f_1(x))))=(f_1 \circ f_2 \circ f_3 \circ f_4)(x)$",
|
||||
"As the latter is more complicated than the former."
|
||||
]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -631,8 +629,8 @@ What is $g_2(x)=f_2^{-1}(x)$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``g_2(x) = x^{-1}``", "``g_2(x) = x``", "``g_2(x) = x -1``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
What is $g_3(x)=f_3^{-1}(x)$?
|
||||
@ -642,8 +640,8 @@ choices = [
|
||||
raw"``c^2/(b\cdot c - a\cdot d) \cdot x``",
|
||||
raw"``(b\cdot c-a\cdot d)/c^2 \cdot x``",
|
||||
raw"``c^2 x``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Given these, what is the value of $g_4(g_3(g_2(g_1(f_4(f_3(f_2(f_1(10))))))))$?
|
||||
|
||||
@ -26,10 +26,6 @@ The [`Julia`](http://www.julialang.org) programming language is well suited as a
|
||||
|
||||
## Interacting with `Julia`
|
||||
|
||||
The html version of the **Calculus With Julia** notes are formatted as
|
||||
Pluto notebooks. `Pluto` is one of many different means for a user to
|
||||
interact with a `Julia` process.
|
||||
|
||||
At a basic level, `Julia` provides a means to read commands or instructions, evaluate those commands, and then print or return those commands. At a user level, there are many different ways to interact with the reading and printing. For example:
|
||||
|
||||
* The REPL. The `Julia` terminal is the built-in means to interact with `Julia`. A `Julia` Terminal has a command prompt, after which commands are typed and then sent to be evaluated by the `enter` key. The terminal may look something like the following where `2+2` is evaluated:
|
||||
@ -57,7 +53,7 @@ julia> 2 + 2
|
||||
|
||||
* A notebook. The [Project Juptyer](https://jupyter.org/) provides a notebook interface for interacting with `Julia` and a more `IDE` style `jupyterlab` interface. A jupyter notebook has cells where commands are typed and immediately following is the printed output returned by `Julia`. The output of a cell depends on the state of the kernel when the cell is computed, not the order of the cells in the notebook. Cells have a number attached, showing the execution order. The `Juypter` notebook is used by `binder` and can be used locally through the `IJulia` package. This notebook has the ability to display many different types of outputs in addition to plain text, such as images, marked up math text, etc.
|
||||
|
||||
* The [Pluto](https://github.com/fonsp/Pluto.jl) package provides a *reactive* notebook interface. Reactive means when one "cell" is modified and executed, the new values cascade to all other dependent cells which in turn are updated. This is very useful for exploring a parameter space, say. These html pages are formatted as `Pluto` notebooks, which makes them able to be easily run on the reader's desktop.
|
||||
* The [Pluto](https://github.com/fonsp/Pluto.jl) package provides a *reactive* notebook interface. Reactive means when one "cell" is modified and executed, the new values cascade to all other dependent cells which in turn are updated. This is very useful for exploring a parameter space, say. Pluto notebooks can be exported as HTML files which make them easy to read online and -- by clever design -- embed the `.jl` file that can run through `Pluto` if it is downloaded.
|
||||
|
||||
|
||||
The `Pluto` interface has some idiosyncracies that need explanation:
|
||||
@ -103,11 +99,9 @@ Pkg.add("CalculusWithJulia")
|
||||
|
||||
This command instructs `Julia` to look at its *general registry* for the `CalculusWithJulia.jl` package, download it, then install it. Once installed, a package only needs to be brought into play with the `using` or `import` commands.
|
||||
|
||||
```julia; echo=false;
|
||||
note("""
|
||||
In a terminal setting, there is a package mode, entered by typing `]` as the leading character and exited by entering `<delete>` at a blank line. This mode allows direct access to `Pkg` with a simpler syntax. The command above would be just `add CalculusWithJulia`.)
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
In a terminal setting, there is a package mode, entered by typing `]` as the leading character and exited by entering `<delete>` at a blank line. This mode allows direct access to `Pkg` with a simpler syntax. The command above would be just `add CalculusWithJulia`.)
|
||||
|
||||
|
||||
|
||||
Packages can be updated through the command `Pkg.up()`, and removed with `Pkg.rm(pkgname)`.
|
||||
@ -129,15 +123,16 @@ Pkg.add("HQuadrature") # for higher-dimensional integration
|
||||
|
||||
## `Julia` commands
|
||||
|
||||
In `Pluto`, commands are typed into a notebook cell:
|
||||
In a `Jupyter` notebook or `Pluto` notebook, commands are typed into a
|
||||
notebook cell:
|
||||
|
||||
```julia;
|
||||
2 + 2 # use shift-enter to evaluate
|
||||
```
|
||||
|
||||
Commands are executed by using `shift-enter` or the run button at the bottom right of a cell.
|
||||
Commands are executed by using `shift-enter` or a run button near the cell.
|
||||
|
||||
Multiple commands per cell are possible if a `begin` or `let` block is used.
|
||||
In `Jupyter` multiple commands per cell are allowed. In `Pluto`, a `begin` or `let` block is used to collect multiple commmands into a single call.
|
||||
Commands may be separated by new lines or semicolons.
|
||||
|
||||
On a given line, anything **after** a `#` is a *comment* and is not processed.
|
||||
@ -146,7 +141,10 @@ The results of the last command executed will be displayed in an
|
||||
output area. Separating values by commas allows more than one value to be
|
||||
displayed. Plots are displayed when the plot object is returned by the last executed command.
|
||||
|
||||
The state of a Pluto notebook is a result of all the cells in the notebook being executed. The cell order does not impact this and can be rearranged by the user.
|
||||
In `Jupyter`, the state of the notebook is a determined by the cells
|
||||
executed along with their order. The state of a `Pluto` notebook is a
|
||||
result of all the cells in the notebook being executed. The cell order
|
||||
does not impact this and can be rearranged by the user.
|
||||
|
||||
## Numbers, variable types
|
||||
|
||||
@ -472,11 +470,9 @@ With `Plots` loaded, we can plot a function by passing the function object by na
|
||||
plot(sin, 0, 2pi) # plot a function - by name - over an interval [a,b]
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
This is in the form of **the** basic pattern employed: `verb(function_object, arguments...)`. The verb in this example is `plot`, the object `sin`, the arguments `0, 2pi` to specify `[a,b]` domain to plot over.
|
||||
""")
|
||||
```
|
||||
!!1 note
|
||||
This is in the form of **the** basic pattern employed: `verb(function_object, arguments...)`. The verb in this example is `plot`, the object `sin`, the arguments `0, 2pi` to specify `[a,b]` domain to plot over.
|
||||
|
||||
|
||||
Plotting more than one function over ```[a,b]``` is achieved through the `plot!` function, which modifies the existing plot (`plot` creates a new one) by adding a new layer:
|
||||
|
||||
|
||||
@ -45,9 +45,9 @@ equal can also be represented with the Unicode `≤` (generated by
|
||||
`\le[tab]`). Similarly, for greater than or equal, there is
|
||||
`\ge[tab]`.
|
||||
|
||||
```julia; echo=false;
|
||||
alert("The use of `==` is necessary, as `=` is used for assignment and mutation.")
|
||||
```
|
||||
!!! warning
|
||||
The use of `==` is necessary, as `=` is used for assignment and mutation.")
|
||||
|
||||
|
||||
The `!` operator takes a boolean value and negates it. It uses prefix notation:
|
||||
|
||||
@ -80,9 +80,9 @@ a < b, a + c < b + c
|
||||
|
||||
Trying other choices will show that the two answers are either both `false` or both `true`.
|
||||
|
||||
```julia; echo=false;
|
||||
alert(""" Well, almost... When `Inf` or `NaN` are involved, this may not hold, for example `1 + Inf < 2 + Inf` is actually `false`. As would be `1 + (typemax(1)-1) < 2 + (typemax(1)-1)`.""")
|
||||
```
|
||||
!!! warning
|
||||
Well, almost... When `Inf` or `NaN` are involved, this may not hold, for example `1 + Inf < 2 + Inf` is actually `false`. As would be `1 + (typemax(1)-1) < 2 + (typemax(1)-1)`.
|
||||
|
||||
|
||||
|
||||
So adding or subtracting most any finite value from an inequality will preserve the inequality, just as it does for equations.
|
||||
@ -131,7 +131,7 @@ In summary we investigated numerically that the following hold:
|
||||
|
||||
- `a < b` if and only if `1/a > 1/b` for all finite, positive `a` and `b`.
|
||||
|
||||
#### Examples
|
||||
### Examples
|
||||
|
||||
We now show some inequalities highlighted on this [Wikipedia](http://en.wikipedia.org/wiki/Inequality_%28mathematics%29) page.
|
||||
|
||||
@ -337,8 +337,8 @@ choices = [
|
||||
"`e^pi` is equal to `pi^e`",
|
||||
"`e^pi` is less than `pi^e`"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -346,8 +346,8 @@ radioq(choices, ans)
|
||||
Is $\sin(1000)$ positive?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
ans = (sin(1000) > 0)
|
||||
yesnoq(ans)
|
||||
answ = (sin(1000) > 0)
|
||||
yesnoq(answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -359,8 +359,8 @@ choices = [
|
||||
"``-1/a < -1/b``",
|
||||
"``-1/a > -1/b``",
|
||||
raw"``-1/a \geq -1/b``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -372,8 +372,8 @@ Suppose you know $a < 0 < b$, is it true that $1/a > 1/b$?
|
||||
choices = ["Yes, it is always true.",
|
||||
"It can sometimes be true, though not always.",
|
||||
L"It is never true, as $1/a$ is negative and $1/b$ is positive"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -394,8 +394,8 @@ $x$. Which of these indicates the first negative value : `airyai(-1) <0`,
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = ["`airyai($i) < 0`" for i in -1:-1:-5]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -406,8 +406,8 @@ By trying three different values of $x > 0$ which of these could possibly be alw
|
||||
choices = ["`x^x <= (1/e)^(1/e)`",
|
||||
"`x^x == (1/e)^(1/e)`",
|
||||
"`x^x >= (1/e)^(1/e)`"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -420,8 +420,8 @@ when $x,y > 0$ and $0 < p < 1$:
|
||||
choices = ["`(x+y)^p < x^p + y^p`",
|
||||
"`(x+y)^p == x^p + y^p`",
|
||||
"`(x+y)^p > x^p + y^p`"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -436,8 +436,8 @@ JSTOR, AMM, Vol.97, No.1, 1990). Which one?
|
||||
choices = ["`a^a + b^b <= a^b + b^a`",
|
||||
"`a^a + b^b >= a^b + b^a`",
|
||||
"`a^b + b^a <= 1`"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -457,8 +457,8 @@ Which of the following is equivalent to $\lvert x - a\rvert > b$:
|
||||
choices = [raw"``-b < x - a < b``",
|
||||
raw"`` -b < x-a \text{ and } x - a < b``",
|
||||
raw"``x - a < -b \text{ or } x - a > b``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -494,8 +494,8 @@ Which of these will show DeMorgan's law holds when both values are `false`:
|
||||
choices = ["`!(false && false) == (!false && !false)`",
|
||||
"`!(false && false) == (false || false)`",
|
||||
"`!(false && false) == (!false || !false)`"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -505,8 +505,8 @@ For floating point numbers there are two special values `Inf` and `NaN`. For whi
|
||||
```julia; hold=true; echo=false;
|
||||
choices = ["`Inf < 3.0` and `3.0 <= Inf`",
|
||||
"`NaN < 3.0` and `3.0 <= NaN`"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -542,8 +542,8 @@ choices = ["""
|
||||
In the manual we can read that "In the expression `a || b`, the subexpression `b` is only evaluated if `a` evaluates to false." In this case `a` is `true` and so `a` is returned.
|
||||
""",
|
||||
"Since the second value is \"`missing`\", only the first is used. So `false || missing` would also be `false`"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
The value for `true && missing` is `missing`, not a boolean value. What happens?
|
||||
@ -553,6 +553,6 @@ choices = ["""
|
||||
In the manual we can read that "In the expression `a && b`, the subexpression `b` is only evaluated if `a` evaluates to true." In this case, `a` is `false` so `b` is evaluated and returned. As `b` is just `missing` that is the return value.
|
||||
""",
|
||||
"Since the second value is \"`missing`\" all such answers would be missing."]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -57,13 +57,11 @@ types through an easy to understand syntax:
|
||||
* rationals are constructed from integers using the double division operator, `//`; and
|
||||
* complex numbers are formed by including a term with the imaginary unit, `im`.
|
||||
|
||||
```julia; echo=false;
|
||||
alert("""
|
||||
Heads up, the difference between `1` and `1.0` is subtle.
|
||||
Even more so, as `1.` will parse as `1.0`.
|
||||
This means some expressions, such as `2.*3`, are ambigous, as the `.` might be part of the `2` (as in `2. * 3`) or the operation `*` (as in `2 .* 3`).
|
||||
""")
|
||||
```
|
||||
!!! warngin
|
||||
Heads up, the difference between `1` and `1.0` is subtle.
|
||||
Even more so, as `1.` will parse as `1.0`.
|
||||
This means some expressions, such as `2.*3`, are ambigous, as the `.` might be part of the `2` (as in `2. * 3`) or the operation `*` (as in `2 .* 3`).
|
||||
|
||||
|
||||
Similarly, each type is printed slightly differently.
|
||||
|
||||
@ -197,22 +195,13 @@ as $a\cdot 2^b$ where $a$ is the *significand* and $b$ is the
|
||||
As per IEEE Standard 754, the `Float64` type gives 52 bits to the precision (with an additional implied one), 11 bits to the exponent and the other bit is used to represent the sign. Positive, finite, floating point numbers have a range approximately between $10^{-308}$ and $10^{308}$, as 308 is about $\log_{10}\cdot 2^{1023}$. The numbers are not evenly spread out over this range, but, rather, are much more concentrated closer to $0$.
|
||||
|
||||
|
||||
```julia; echo=false;
|
||||
alert("""
|
||||
You can discover more about the range of floating point values provided by calling a few different functions.
|
||||
|
||||
- `typemax(0.0)` gives the largest value for the type (`Inf` in this case).
|
||||
|
||||
- `prevfloat(Inf)` gives the largest finite one, in general `prevfloat` is the next smallest floating point value.
|
||||
|
||||
- `nextfloat(-Inf)`, similarly, gives the smallest finite floating point value, and in general returns the next largest floating point value.
|
||||
|
||||
- `nextfloat(0.0)` gives the closest positive value to 0.
|
||||
|
||||
- `eps()` gives the distance to the next floating point number bigger than `1.0`. This is sometimes referred to as machine precision.
|
||||
|
||||
""", title="More on floating point", label="More on the range of floating point values")
|
||||
```
|
||||
!!! warning "More on floating point numbers"
|
||||
You can discover more about the range of floating point values provided by calling a few different functions.
|
||||
* `typemax(0.0)` gives the largest value for the type (`Inf` in this case).
|
||||
* `prevfloat(Inf)` gives the largest finite one, in general `prevfloat` is the next smallest floating point value.
|
||||
* `nextfloat(-Inf)`, similarly, gives the smallest finite floating point value, and in general returns the next largest floating point value.
|
||||
* `nextfloat(0.0)` gives the closest positive value to 0.
|
||||
* `eps()` gives the distance to the next floating point number bigger than `1.0`. This is sometimes referred to as machine precision.
|
||||
|
||||
#### Scientific notation
|
||||
|
||||
@ -421,11 +410,9 @@ discr = b^2 - 4a*c
|
||||
|
||||
When learning calculus, the only common usage of complex numbers arises when solving polynomial equations for roots, or zeros, though they are very important for subsequent work using the concepts of calculus.
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
Though complex numbers are stored as pairs of numbers, the imaginary unit, `im`, is of type `Complex{Bool}`, a type that can be promoted to more specific types when `im` is used with different number types.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Though complex numbers are stored as pairs of numbers, the imaginary unit, `im`, is of type `Complex{Bool}`, a type that can be promoted to more specific types when `im` is used with different number types.
|
||||
|
||||
|
||||
|
||||
## Type stability
|
||||
@ -560,8 +547,8 @@ The number created by `pi/2` is?
|
||||
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -569,8 +556,8 @@ radioq(choices, ans, keep_order=true)
|
||||
The number created by `2/2` is?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -578,8 +565,8 @@ radioq(choices, ans, keep_order=true)
|
||||
The number created by `2//2` is?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -587,8 +574,8 @@ radioq(choices, ans, keep_order=true)
|
||||
The number created by `1 + 1//2 + 1/3` is?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -597,8 +584,8 @@ radioq(choices, ans, keep_order=true)
|
||||
The number created by `2^3` is?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -607,8 +594,8 @@ radioq(choices, ans, keep_order=true)
|
||||
The number created by `sqrt(im)` is?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -617,8 +604,8 @@ radioq(choices, ans, keep_order=true)
|
||||
The number created by `2^(-1)` is?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -628,8 +615,8 @@ radioq(choices, ans, keep_order=true)
|
||||
The "number" created by `1/0` is?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
@ -75,10 +75,8 @@ using Plots
|
||||
```
|
||||
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
`Plots` is a frontend for one of several backends. `Plots` comes with a backend for web-based graphics (call `plotly()` to specify that); a backend for static graphs (call `gr()` for that). If the `PyPlot` package is installed, calling `pyplot()` will set that as a backend. For terminal usage, if the `UnicodePlots` package is installed, calling `unicodeplots()` will enable that usage. There are still other backends.""")
|
||||
```
|
||||
!!! note
|
||||
`Plots` is a frontend for one of several backends. `Plots` comes with a backend for web-based graphics (call `plotly()` to specify that); a backend for static graphs (call `gr()` for that). If the `PyPlot` package is installed, calling `pyplot()` will set that as a backend. For terminal usage, if the `UnicodePlots` package is installed, calling `unicodeplots()` will enable that usage. There are still other backends.
|
||||
|
||||
The `plotly` backend is part of the `Plots` package, as is `gr`. Other backends require installation, such as `PyPlot` and `PlotlyJS`.
|
||||
We use `gr` in these notes, for the most part. (The `plotly` backend is also quite nice for interactive usage, but doesn't work as well with the static HTML pages.)
|
||||
@ -112,11 +110,9 @@ Plotting a function is then this simple: `plot(f, xmin, xmax)`.
|
||||
> style, where the details to execute the action are only exposed as
|
||||
> needed.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The time to first plot can feel sluggish, but subsequent plots will be speedy. See the technical note at the end of this section for an explanation.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The time to first plot can feel sluggish, but subsequent plots will be speedy. See the technical note at the end of this section for an explanation.
|
||||
|
||||
|
||||
Let's see some other graphs.
|
||||
|
||||
@ -165,16 +161,12 @@ plot(x -> mxplusb(x, (m=-1, b=1)), -1, 2)
|
||||
```
|
||||
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
!!! note
|
||||
The function object in the general pattern `action(function, args...)`
|
||||
is commonly specified in one of three ways: by a name, as with `f`; as an
|
||||
anonymous function; or as the return value of some other action
|
||||
through composition.
|
||||
|
||||
The function object in the general pattern `action(function, args...)`
|
||||
is commonly specified in one of three ways: by a name, as with `f`; as an
|
||||
anonymous function; or as the return value of some other action
|
||||
through composition.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
Anonymous functions are also created by `Julia's` `do` notation, which is useful when the first argument to function (like `plot`) accepts a function:
|
||||
|
||||
@ -186,11 +178,9 @@ end
|
||||
|
||||
The `do` notation can be a bit confusing to read when unfamiliar, though its convenience makes it appealing.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
Some types we will encounter, such as the one for symbolic values or the special polynomial one, have their own `plot` recipes that allow them to be plotted similarly as above, even though they are not functions.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Some types we will encounter, such as the one for symbolic values or the special polynomial one, have their own `plot` recipes that allow them to be plotted similarly as above, even though they are not functions.
|
||||
|
||||
|
||||
----
|
||||
|
||||
@ -248,22 +238,6 @@ pts_needed(x -> 10x, 0, 10), pts_needed(x -> sin(10x), 0, 10)
|
||||
(In fact, the `21` is the minimum number of points used for any function; a linear function only needs two.)
|
||||
|
||||
|
||||
##### Example
|
||||
|
||||
This demo (which is interactive within a `Pluto` session) shows more points are needed as the function becomes more "curvy." There are the minimum of ``21`` for a straight line, ``37`` for a half period, ``45`` for a full period, etc.
|
||||
|
||||
```julia; echo=false
|
||||
md"""
|
||||
n = $(@bind 𝐧 Slider(0:20, default=1))
|
||||
"""
|
||||
```
|
||||
|
||||
```julia; hold=true;
|
||||
xs,ys = unzip(x -> sin(𝐧*x*pi), 0, 1)
|
||||
plot(xs, ys, title="n=$(length(xs))")
|
||||
scatter!(xs, ys)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
For instances where a *specific* set of ``x`` values is desired to be
|
||||
@ -495,16 +469,12 @@ The ``3`` main functions used in these notes for adding layers are:
|
||||
* `annotate!((x,y, label))` to add a label at $(x,y)$
|
||||
|
||||
|
||||
```julia;echo=false
|
||||
alert("""
|
||||
!!! warning
|
||||
Julia has a convention to use functions named with a `!` suffix to
|
||||
indicate that they mutate some object. In this case, the object is the
|
||||
current graph, though it is implicit. Both `plot!`, `scatter!`, and
|
||||
`annotate!` (others too) do this by adding a layer.
|
||||
|
||||
Julia has a convention to use functions named with a `!` suffix to
|
||||
indicate that they mutate some object. In this case, the object is the
|
||||
current graph, though it is implicit. Both `plot!`, `scatter!`, and
|
||||
`annotate!` (others too) do this by adding a layer.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
## Additional arguments
|
||||
|
||||
@ -709,8 +679,8 @@ choices = ["`(-Inf, -1)` and `(0,1)`",
|
||||
"`(-Inf, -0.577)` and `(0.577, Inf)`",
|
||||
"`(-1, 0)` and `(1, Inf)`"
|
||||
];
|
||||
ans=3;
|
||||
radioq(choices, ans)
|
||||
answ=3;
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -737,8 +707,8 @@ choices = ["`(-Inf, -3)` and `(0, 1)`",
|
||||
"`(-3, 0)` and `(1, Inf)`",
|
||||
"`(-Inf, -4.1)` and `(1.455, Inf)`"
|
||||
];
|
||||
ans=2;
|
||||
radioq(choices, ans)
|
||||
answ=2;
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -787,15 +757,15 @@ choices = [
|
||||
"`f(x) = x <= 4 ? 35.0 : 35.0 + 10.0 * (x-4)`",
|
||||
"`f(x) = x <= 10 ? 35.0 : 35.0 + 4.0 * (x-10)`"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Make a plot of the model. Graphically estimate how many bags of trash will cost 55 dollars.
|
||||
|
||||
```julia; hold=true;echo=false
|
||||
ans = 15
|
||||
numericq(ans, .5)
|
||||
answ = 15
|
||||
numericq(answ, .5)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -829,8 +799,8 @@ What is seen?
|
||||
choices = [L"It oscillates wildly, as the period is $T=2\pi/(500 \pi)$ so there are 250 oscillations.",
|
||||
"It should oscillate evenly, but instead doesn't oscillate very much near 0 and 1",
|
||||
L"Oddly, it looks exactly like the graph of $f(x) = \sin(2\pi x)$."]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
The algorithm to plot a function works to avoid aliasing issues. Does the graph generated by `plot(f, 0, 1)` look the same, as the one above?
|
||||
@ -840,8 +810,8 @@ choices = ["Yes",
|
||||
"No, but is still looks pretty bad, as fitting 250 periods into a too small number of pixels is a problem.",
|
||||
"No, the graph shows clearly all 250 periods."
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -865,8 +835,8 @@ choices = [
|
||||
"An ellipse",
|
||||
"A straight line"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -898,8 +868,8 @@ choices = [
|
||||
"A straight line",
|
||||
"None of the above"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -917,8 +887,8 @@ choices = [
|
||||
"A straight line",
|
||||
"None of the above"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans,keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ,keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -936,8 +906,8 @@ choices = [
|
||||
"A straight line",
|
||||
"None of the above"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
|
||||
@ -956,8 +926,8 @@ choices = [
|
||||
"A straight line",
|
||||
"None of the above"
|
||||
]
|
||||
ans = 5
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 5
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
In this section we use the following add-on packages:
|
||||
|
||||
|
||||
```julia
|
||||
using SymPy
|
||||
using Plots
|
||||
@ -11,6 +12,8 @@ using Plots
|
||||
using CalculusWithJulia
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
fig_size = (800, 600) #400, 300)
|
||||
|
||||
const frontmatter = (
|
||||
title = "Polynomials",
|
||||
description = "Calculus with Julia: Polynomials",
|
||||
@ -19,6 +22,7 @@ const frontmatter = (
|
||||
nothing
|
||||
```
|
||||
|
||||
|
||||
----
|
||||
|
||||
Polynomials are a particular class of expressions that are simple
|
||||
@ -57,7 +61,7 @@ a_n x^n + a_{n-1}x^{n-1} + \cdots a_1 x + a_0, \quad a_n \neq 0
|
||||
```julia; hold=true; echo=false; cache=true
|
||||
##{{{ different_poly_graph }}}
|
||||
|
||||
fig_size = (400, 300)
|
||||
|
||||
anim = @animate for m in 2:2:10
|
||||
fn = x -> x^m
|
||||
plot(fn, -1, 1, size = fig_size, legend=false, title="graph of x^{$m}", xlims=(-1,1), ylims=(-.1,1))
|
||||
@ -109,11 +113,9 @@ of $m$ can be found from two points through the well-known formula:
|
||||
m = \frac{y_1 - y_0}{x_1 - x_0} = \frac{\text{rise}}{\text{run}}
|
||||
```
|
||||
|
||||
```julia; hold=true, echo=false; cache=true
|
||||
```julia; hold=true; echo=false; cache=true
|
||||
### {{{ lines_m_graph }}}
|
||||
|
||||
fig_size = (400, 300)
|
||||
|
||||
anim = @animate for m in [-5, -2, -1, 1, 2, 5, 10, 20]
|
||||
fn = x -> m * x
|
||||
plot(fn, -1, 1, size = fig_size, legend=false, title="m = $m", xlims=(-1,1), ylims=(-20, 20))
|
||||
@ -177,21 +179,13 @@ Python session. That is great for `Julia` users, as the `PyCall` and
|
||||
manner. This allows the `Julia` package `SymPy` to provide
|
||||
functionality from SymPy within `Julia`.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
!!! note
|
||||
When `SymPy` is installed through the package manger, the underlying `Python`
|
||||
libraries will also be installed.
|
||||
|
||||
When `SymPy` is installed through the package manger, the underlying `Python`
|
||||
libraries will also be installed.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The [`Symbolics`](../alternatives/symbolics) package is a rapidly
|
||||
developing `Julia`-only packge that provides symbolic math options.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The [`Symbolics`](../alternatives/symbolics) package is a rapidly
|
||||
developing `Julia`-only packge that provides symbolic math options.
|
||||
|
||||
----
|
||||
|
||||
@ -212,10 +206,8 @@ that can be made. The `@syms` macro documentation lists them. The
|
||||
symbols. The *macro* `@syms` does not need assignment, as the
|
||||
variable(s) are created behind the scenes by the macro.
|
||||
|
||||
```julia;echo=false
|
||||
note("""Macros in `Julia` are just transformations of the syntax into other syntax. The `@` indicates they behave differently than regular function calls.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
Macros in `Julia` are just transformations of the syntax into other syntax. The `@` indicates they behave differently than regular function calls.
|
||||
|
||||
|
||||
The `SymPy` package does three basic things:
|
||||
@ -440,8 +432,6 @@ larger values of $n$ have greater growth once outside of $[-1,1]$:
|
||||
```julia; hold=true; echo=false; cache=true
|
||||
### {{{ poly_growth_graph }}}
|
||||
|
||||
fig_size = (400, 300)
|
||||
|
||||
anim = @animate for m in 0:2:12
|
||||
fn = x -> x^m
|
||||
plot(fn, -1.2, 1.2, size = fig_size, legend=false, xlims=(-1.2, 1.2), ylims=(0, 1.2^12), title="x^{$m} over [-1.2, 1.2]")
|
||||
@ -482,8 +472,6 @@ of the plot window until the graph appears U-shaped.
|
||||
```julia;hold=true; echo=false; cache=true
|
||||
### {{{ leading_term_graph }}}
|
||||
|
||||
fig_size = (400, 300)
|
||||
|
||||
anim = @animate for n in 1:6
|
||||
m = [1, .5, -1, -5, -20, -25]
|
||||
M = [2, 4, 5, 10, 25, 30]
|
||||
@ -728,8 +716,8 @@ What is the leading term of $p$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["``3``", "``3x^2``", "``-2x``", "``5``"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -761,8 +749,8 @@ The linear polynomial $p = 2x + 3$ is written in which form:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["point-slope form", "slope-intercept form", "general form"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -781,8 +769,8 @@ What command will return the value of the polynomial when $x=2$?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = [q"p*2", q"p[2]", q"p_2", q"p(x=>2)"]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -796,8 +784,8 @@ L"Be $U$-shaped, opening upward",
|
||||
L"Be $U$-shaped, opening downward",
|
||||
L"Overall, go upwards from $-\infty$ to $+\infty$",
|
||||
L"Overall, go downwards from $+\infty$ to $-\infty$"]
|
||||
ans = 3
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 3
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -810,8 +798,8 @@ L"Be $U$-shaped, opening upward",
|
||||
L"Be $U$-shaped, opening downward",
|
||||
L"Overall, go upwards from $-\infty$ to $+\infty$",
|
||||
L"Overall, go downwards from $+\infty$ to $-\infty$"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -824,8 +812,8 @@ L"Be $U$-shaped, opening upward",
|
||||
L"Be $U$-shaped, opening downward",
|
||||
L"Overall, go upwards from $-\infty$ to $+\infty$",
|
||||
L"Overall, go downwards from $+\infty$ to $-\infty$"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -860,7 +848,7 @@ choices = [q"x^3 - 3x^2 + 2x",
|
||||
q"x^3 - x^2 - 2x",
|
||||
q"x^3 + x^2 - 2x",
|
||||
q"x^3 + x^2 + 2x"]
|
||||
ans = 2
|
||||
answ = 2
|
||||
radioq(choices, 2)
|
||||
```
|
||||
|
||||
@ -874,6 +862,6 @@ q"-h^2 + 3hx - 3x^2",
|
||||
q"h^3 + 3h^2x + 3hx^2 + x^3 -x^3/h",
|
||||
q"x^3 - x^3/h",
|
||||
q"0"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -2,7 +2,8 @@
|
||||
|
||||
In this section we use the following add on packages:
|
||||
|
||||
```juila
|
||||
|
||||
```julia
|
||||
using CalculusWithJulia
|
||||
using Plots
|
||||
using SymPy
|
||||
@ -191,11 +192,9 @@ quotient, remainder = divrem(x^4 + 2x^2 + 5, x - 2)
|
||||
|
||||
The answer is a tuple containing the quotient and remainder. The quotient itself could be found with `div` or `÷` and the remainder with `rem`.
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
For those who have worked with SymPy within Python, `divrem` is the `div` method renamed, as `Julia`'s `div` method has the generic meaning of returning the quotient.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
For those who have worked with SymPy within Python, `divrem` is the `div` method renamed, as `Julia`'s `div` method has the generic meaning of returning the quotient.
|
||||
|
||||
|
||||
|
||||
As well, the `apart` function could be used for this task. This function
|
||||
@ -286,12 +285,11 @@ multiplicity must be accounted for and $x^2 + 1$ to see why complex
|
||||
values may be necessary.)
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
alert(raw"""
|
||||
The special case of the ``0`` polynomial having no degree defined
|
||||
eliminates needing to exclude it, as it has infinitely many roots. Otherwise, the language would be qualified to have ``n \geq 0``.
|
||||
""")
|
||||
```
|
||||
!!! warning
|
||||
The special case of the ``0`` polynomial having no degree defined
|
||||
eliminates needing to exclude it, as it has infinitely many roots.
|
||||
Otherwise, the language would be qualified to have ``n \geq 0``.
|
||||
|
||||
|
||||
## Finding roots of a polynomial
|
||||
|
||||
@ -458,11 +456,9 @@ q = sympy.Poly(p, x) # identify `x` as indeterminate; alternatively p.as_poly(x
|
||||
roots(q)
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The sympy `Poly` function must be found within the underlying `sympy` module, a Python object, hence is qualified as `sympy.Poly`. This is common when using `SymPy`, as only a small handful of the many functions available are turned into `Julia` functions, the rest are used as would be done in Python. (This is similar, but different than qualifying by a `Julia` module when there are two conflicting names. An example will be the use of the name `roots` in both `SymPy` and `Polynomials` to refer to a function that finds the roots of a polynomial. If both functions were loaded, then the last line in the above example would need to be `SymPy.roots(q)` (note the capitalization.)
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The sympy `Poly` function must be found within the underlying `sympy` module, a Python object, hence is qualified as `sympy.Poly`. This is common when using `SymPy`, as only a small handful of the many functions available are turned into `Julia` functions, the rest are used as would be done in Python. (This is similar, but different than qualifying by a `Julia` module when there are two conflicting names. An example will be the use of the name `roots` in both `SymPy` and `Polynomials` to refer to a function that finds the roots of a polynomial. If both functions were loaded, then the last line in the above example would need to be `SymPy.roots(q)` (note the capitalization.)
|
||||
|
||||
### Numerically finding roots
|
||||
|
||||
The `solve` function can be used to get numeric approximations to the
|
||||
@ -583,11 +579,9 @@ in fact there are three, two are *very* close together:
|
||||
N.(solve(h))
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The difference of the two roots is around `1e-10`. For the graph over the interval of ``[-5,7]`` there are about ``800`` "pixels" used, so each pixel represents a size of about `1.5e-2`. So the cluster of roots would safely be hidden under a single "pixel."
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The difference of the two roots is around `1e-10`. For the graph over the interval of ``[-5,7]`` there are about ``800`` "pixels" used, so each pixel represents a size of about `1.5e-2`. So the cluster of roots would safely be hidden under a single "pixel."
|
||||
|
||||
|
||||
The point of this is to say, that it is useful to know where to look
|
||||
for roots, even if graphing calculators or graphing programs make
|
||||
@ -713,8 +707,8 @@ choices = [
|
||||
"``6``",
|
||||
"``0``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -728,8 +722,8 @@ choices = [
|
||||
"``x^2 - 2x + 2``",
|
||||
"``2``"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -744,8 +738,8 @@ choices = [
|
||||
"``x^3 + x^2 - 1``",
|
||||
"``-2x + 2``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -770,8 +764,8 @@ choices = [
|
||||
"``x^5 + 2x^4 + 4x^3 + 8x^2 + 15x + 31``",
|
||||
"``x^4 +2x^3 + 4x^2 + 8x + 15``",
|
||||
"``31``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -784,8 +778,8 @@ choices = [
|
||||
"``x^5 + 2x^4 + 4x^3 + 8x^2 + 15x + 31``",
|
||||
"``x^4 +2x^3 + 4x^2 + 8x + 15``",
|
||||
"``31``"]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
What is $r$?
|
||||
@ -797,8 +791,8 @@ choices = [
|
||||
"``x^5 + 2x^4 + 4x^3 + 8x^2 + 15x + 31``",
|
||||
"``x^4 +2x^3 + 4x^2 + 8x + 15``",
|
||||
"``31``"]
|
||||
ans = 5
|
||||
radioq(choices, ans)
|
||||
answ = 5
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -813,8 +807,8 @@ choices = [
|
||||
L" $2$ and $3$",
|
||||
L" $(x-2)$ and $(x-3)$",
|
||||
L" $(x+2)$ and $(x+3)$"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -860,8 +854,8 @@ q"[-0.434235, -0.434235, 0.188049, 0.188049, 0.578696, 4.91368]",
|
||||
q"[-0.434235, -0.434235, 0.188049, 0.188049]",
|
||||
q"[0.578696, 4.91368]",
|
||||
q"[-0.434235+0.613836im, -0.434235-0.613836im]"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -916,8 +910,8 @@ numericq(1)
|
||||
Let $f(x) = x^5 - 4x^4 + x^3 - 2x^2 + x$. What does Cauchy's bound say is the largest possible magnitude of a root?
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
ans = 1 + 4 + 1 + 2 + 1
|
||||
numericq(ans)
|
||||
answ = 1 + 4 + 1 + 2 + 1
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
What is the largest magnitude of a real root?
|
||||
@ -925,8 +919,8 @@ What is the largest magnitude of a real root?
|
||||
```julia; hold=true; echo=false
|
||||
f(x) = x^5 - 4x^4 + x^3 - 2x^2 + x
|
||||
rts = find_zeros(f, -5..5)
|
||||
ans = maximum(abs.(rts))
|
||||
numericq(ans)
|
||||
answ = maximum(abs.(rts))
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
|
||||
@ -970,8 +964,8 @@ choices = [
|
||||
"``2x^2``",
|
||||
"``x``",
|
||||
"``2x``"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
* True or false, the $degree$ of $T_n(x)$ is $n$: (Look at the defining relation and reason this out).
|
||||
@ -992,8 +986,8 @@ The Chebyshev polynomials have the property that in fact all $n$ roots are real,
|
||||
@syms x
|
||||
p = 16x^5 - 20x^3 + 5x
|
||||
rts = N.(solve(p))
|
||||
ans = maximum(norm.(rts))
|
||||
numericq(ans)
|
||||
answ = maximum(norm.(rts))
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
* Plotting `p` over the interval $[-2,2]$ does not help graphically identify the roots:
|
||||
|
||||
@ -187,11 +187,8 @@ observed from the output. The lone real root is approximately
|
||||
irrational root.
|
||||
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
`SymPy` also has a `roots` function. If both `Polynomials` and `SymPy` are used together, calling `roots` must be qualified, as with `Polynomials.roots(...)`. Similarly, `degree` is provided in both, so it too must be qualified.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
`SymPy` also has a `roots` function. If both `Polynomials` and `SymPy` are used together, calling `roots` must be qualified, as with `Polynomials.roots(...)`. Similarly, `degree` is provided in both, so it too must be qualified.
|
||||
|
||||
|
||||
The `roots` function numerically identifies roots. As such, it is susceptible to floating point issues. For example, the following polynomial has one root with multiplicity ``5``, but ``5`` distinct roots are numerically identified:
|
||||
@ -352,8 +349,8 @@ Mathematically we say the ``0`` polynomial has no degree. What convention does `
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = ["`nothing`", "`-1`", "`0`", "`Inf`", "`-Inf`"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -511,10 +508,7 @@ It is ``0\cdot T_1(x) + 1\cdot T_1(x) + 2\cdot T_2(x) + 3\cdot T_3(x) = -2 - 8\c
|
||||
radioq(choices, 3)
|
||||
```
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
note("""
|
||||
The `Polynomials` package has an implementation, so you can check your answer through `convert(Polynomial, ChebyshevT([0,1,2,3]))`. Similarly, the `SpecialPolynomials` package has these and many other polynomial bases represented.
|
||||
!!! note
|
||||
The `Polynomials` package has an implementation, so you can check your answer through `convert(Polynomial, ChebyshevT([0,1,2,3]))`. Similarly, the `SpecialPolynomials` package has these and many other polynomial bases represented.
|
||||
|
||||
The `ApproxFun` package is built on top of polynomials expressed in this basis, as the Chebyshev polynomials have special properties which make them very suitable when approximating functions with polynomials. The `ApproxFun` package uses easier-to-manipulate polynomials to approximate functions very accurately, thereby being useful for investigating properties of non-linear functions leveraging properties for polynomials.
|
||||
""")
|
||||
```
|
||||
The `ApproxFun` package is built on top of polynomials expressed in this basis, as the Chebyshev polynomials have special properties which make them very suitable when approximating functions with polynomials. The `ApproxFun` package uses easier-to-manipulate polynomials to approximate functions very accurately, thereby being useful for investigating properties of non-linear functions leveraging properties for polynomials.
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
const frontmatter = (
|
||||
frontmatter = (
|
||||
title = "Ranges and Sets",
|
||||
description = "Calculus with Julia: Ranges and Sets",
|
||||
tags = ["CalculusWithJulia", "precalc", "ranges and sets"],
|
||||
@ -155,7 +155,7 @@ collected to realize the values.
|
||||
The number of points is specified with keyword arguments, as in:
|
||||
|
||||
```julia;
|
||||
xs = range(-1, 1, length=9) # or simply range(-1, 1, 9)
|
||||
xs = range(-1, 1, length=9) # or simply range(-1, 1, 9) as of v"1.7"
|
||||
```
|
||||
|
||||
and
|
||||
@ -164,11 +164,9 @@ and
|
||||
collect(xs)
|
||||
```
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
There is also the `LinRange(a, b, n)` function which can be more performant than `range`, as it doesn't try to correct for floating point errors.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
There is also the `LinRange(a, b, n)` function which can be more performant than `range`, as it doesn't try to correct for floating point errors.
|
||||
|
||||
|
||||
## Modifying sequences
|
||||
|
||||
@ -466,8 +464,8 @@ q"1:99",
|
||||
q"1:3:99",
|
||||
q"1:2:99"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -477,8 +475,8 @@ Which of these will create the sequence $2, 9, 16, 23, \dots, 72$?
|
||||
|
||||
```julia; hold=true;echo=false;
|
||||
choices = [q"2:7:72", q"2:9:72", q"2:72", q"72:-7:2"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -502,8 +500,8 @@ choices = [
|
||||
"`1:-1:10`",
|
||||
"`1:10`"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -538,8 +536,8 @@ choices = ["It is just random",
|
||||
"Addition happens prior to the use of `:` so this is like `1:(4+2):5`",
|
||||
"It gives the correct answer, a generator for the vector `[3,5,7,9]`"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -548,8 +546,8 @@ How is `a:b-1` interpreted:
|
||||
|
||||
```julia; hold=true;echo=false;
|
||||
choices = ["as `a:(b-1)`", "as `(a:b) - 1`, which is `(a-1):(b-1)`"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -558,8 +556,8 @@ Create the sequence $10, 100, 1000, \dots, 1,000,000$ using a list comprehension
|
||||
|
||||
```julia; hold=true;echo=false;
|
||||
choices = [q"[10^i for i in 1:6]", q"[10^i for i in [10, 100, 1000]]", q"[i^10 for i in [1:6]]"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -571,8 +569,8 @@ choices = [
|
||||
q"[10^-i for i in 1:7]",
|
||||
q"[(1/10)^i for i in 1:7]",
|
||||
q"[i^(1/10) for i in 1:7]"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -581,8 +579,8 @@ Evaluate the expression $x^3 - 2x + 3$ for each of the values $-5, -4, \dots, 4,
|
||||
|
||||
```julia; hold=true;echo=false;
|
||||
choices = [q"[x^3 - 2x + 3 for i in -5:5]", q"[x^3 - 2x + 3 for x in -(5:5)]", q"[x^3 - 2x + 3 for x in -5:5]"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
@ -260,7 +260,7 @@ saying it follows the shape of the leading term of $q(x)$, at the
|
||||
expense of the work required to find $q(x)$.
|
||||
|
||||
|
||||
##### Examples
|
||||
### Examples
|
||||
|
||||
|
||||
Consider the rational expression
|
||||
@ -853,8 +853,8 @@ The rational expression $(x^3 - 2x + 3) / (x^2 - x + 1)$ would have
|
||||
choices = [L"A horizontal asymptote $y=0$",
|
||||
L"A horizontal asymptote $y=1$",
|
||||
L"A slant asymptote with slope $m=1$"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -866,8 +866,8 @@ The rational expression $(x^2 - x + 1)/ (x^3 - 2x + 3)$ would have
|
||||
choices = [L"A horizontal asymptote $y=0$",
|
||||
L"A horizontal asymptote $y=1$",
|
||||
L"A slant asymptote with slope $m=1$"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -881,8 +881,8 @@ The rational expression $(x^2 - x + 1)/ (x^2 - 3x + 3)$ would have
|
||||
choices = [L"A horizontal asymptote $y=0$",
|
||||
L"A horizontal asymptote $y=1$",
|
||||
L"A slant asymptote with slope $m=1$"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -902,8 +902,8 @@ would have
|
||||
choices = [L"A horizontal asymptote $y=0$",
|
||||
L"A horizontal asymptote $y=1$",
|
||||
L"A slant asymptote with slope $m=1$"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -923,8 +923,8 @@ choices = [L"A vertical asymptote $x=1$",
|
||||
L"A slant asymptote with slope $m=1$",
|
||||
L"A vertical asymptote $x=5$"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -946,8 +946,8 @@ choices = [
|
||||
"``y = (1/3)x``",
|
||||
"``y = (1/3)x - (1/3)``"
|
||||
]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -971,8 +971,8 @@ Is the following common conception true: "The graph of a function never crosses
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["No, the graph clearly crosses the drawn asymptote",
|
||||
"Yes, this is true"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
(The wikipedia page indicates that the term "asymptote" was introduced
|
||||
@ -1002,8 +1002,8 @@ choices = ["The horizontal asymptote is not a straight line.",
|
||||
L"The $y$-axis scale shows that indeed the $y$ values are getting close to $0$.",
|
||||
L"The graph is always decreasing, hence it will eventually reach $-\infty$."
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1040,8 +1040,8 @@ choices = ["between ``0`` and ``8`` hours",
|
||||
"between ``8`` and ``16`` hours",
|
||||
"between ``16`` and ``24`` hours",
|
||||
"after one day"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
This graph has
|
||||
@ -1051,8 +1051,8 @@ choices = [L"a slant asymptote with slope $50$",
|
||||
L"a horizontal asymptote $y=20$",
|
||||
L"a horizontal asymptote $y=0$",
|
||||
L"a vertical asymptote with $x = 20^{1/3}$"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -1073,6 +1073,6 @@ L"The $\sin(x)$ oscillates, but the rational function eventually follows $7/60 \
|
||||
L"The $\sin(x)$ oscillates, but the rational function has a slant asymptote",
|
||||
L"The $\sin(x)$ oscillates, but the rational function has a non-zero horizontal asymptote",
|
||||
L"The $\sin(x)$ oscillates, but the rational function has a horizontal asymptote of $0$"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -114,17 +114,13 @@ plot!(gf, label="g∘f")
|
||||
```
|
||||
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
!!! note
|
||||
Unlike how the basic arithmetic operations are treated, `Julia` defines the infix
|
||||
Unicode operator `\\circ[tab]` to represent composition of functions,
|
||||
mirroring mathematical notation. This infix operations takes in two functions and returns an anonymous function. It
|
||||
can be useful and will mirror standard mathematical usage up to issues
|
||||
with precedence rules.
|
||||
|
||||
Unlike how the basic arithmetic operations are treated, `Julia` defines the infix
|
||||
Unicode operator `\\circ[tab]` to represent composition of functions,
|
||||
mirroring mathematical notation. This infix operations takes in two functions and returns an anonymous function. It
|
||||
can be useful and will mirror standard mathematical usage up to issues
|
||||
with precedence rules.
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
Starting with two functions and composing them requires nothing more
|
||||
than a solid grasp of knowing the rules of function evaluation. If
|
||||
@ -163,11 +159,9 @@ other compositions could have been given above. For example, the last
|
||||
function is also $f(x) = e^{-x/2}$ composed with $g(x) = x^2$.
|
||||
|
||||
|
||||
```julia;echo=false
|
||||
note("""
|
||||
The real value of composition is to break down more complicated things into a sequence of easier steps. This is good mathematics, but also good practice more generally. For example, when we approach a problem with the computer, we generally use a smallish set of functions and piece them together (that is, compose them) to find a solution.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The real value of composition is to break down more complicated things into a sequence of easier steps. This is good mathematics, but also good practice more generally. For example, when we approach a problem with the computer, we generally use a smallish set of functions and piece them together (that is, compose them) to find a solution.
|
||||
|
||||
|
||||
### Shifting and scaling graphs
|
||||
|
||||
@ -508,8 +502,8 @@ If $f(x) = 1/x$ and $g(x) = x-2$, what is $g(f(x))$?
|
||||
|
||||
```julia; hold=true;echo=false
|
||||
choices=["``1/(x-2)``", "``1/x - 2``", "``x - 2``", "``-2``"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -519,8 +513,8 @@ If $f(x) = e^{-x}$ and $g(x) = x^2$ and $h(x) = x-3$, what is $f \circ g \circ h
|
||||
```julia; hold=true;echo=false
|
||||
choices=["``e^{-x^2 - 3}``", "``(e^x -3)^2``",
|
||||
"``e^{-(x-3)^2}``", "``e^x+x^2+x-3``"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -530,8 +524,8 @@ If $h(x) = (f \circ g)(x) = \sin^2(x)$ which is a possibility for $f$ and $g$:
|
||||
choices = [raw"``f(x)=x^2; \quad g(x) = \sin^2(x)``",
|
||||
raw"```f(x)=x^2; \quad g(x) = \sin(x)``",
|
||||
raw"``f(x)=\sin(x); \quad g(x) = x^2``"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -544,7 +538,7 @@ choices = [
|
||||
raw"``h(x) = 6 + \sin(x + 4)``",
|
||||
raw"``h(x) = 6 + \sin(x-4)``",
|
||||
raw"``h(x) = 6\sin(x-4)``"]
|
||||
ans = 3
|
||||
answ = 3
|
||||
radioq(choices, 3)
|
||||
```
|
||||
|
||||
@ -555,8 +549,8 @@ Let $h(x) = 4x^2$ and $f(x) = x^2$. Which is **not** true:
|
||||
choices = [L"The graph of $h(x)$ is the graph of $f(x)$ stretched by a factor of ``4``",
|
||||
L"The graph of $h(x)$ is the graph of $f(x)$ scaled by a factor of ``2``",
|
||||
L"The graph of $h(x)$ is the graph of $f(x) shifted up by ``4`` units"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -567,8 +561,8 @@ The transformation $h(x) = (1/a) \cdot f((x-b)/a)$ can be viewed in one sequence
|
||||
choices = [L"scaling by $1/a$, then shifting by $b$, then stretching by $1/a$",
|
||||
L"shifting by $a$, then scaling by $b$, and then scaling by $1/a$",
|
||||
L"shifting by $a$, then scaling by $a$, and then scaling by $b$" ]
|
||||
ans=1
|
||||
radioq(choices, ans)
|
||||
answ=1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -603,8 +597,8 @@ raw"``\sin(2x)``",
|
||||
raw"``\sin(\pi x)``",
|
||||
raw"``2 \sin(\pi x)``"
|
||||
]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -626,8 +620,8 @@ choices = [
|
||||
q"D(S(f))(n) = f(n)",
|
||||
q"S(D(f))(n) = f(n) - f(0)"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -645,6 +639,6 @@ choices = [
|
||||
q"D(S(f))(n) = f(n)",
|
||||
q"S(D(f))(n) = f(n) - f(0)"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
# Trigonometric functions
|
||||
|
||||
|
||||
This section uses the following add-on packages:
|
||||
|
||||
```julia
|
||||
@ -11,6 +12,8 @@ using SymPy
|
||||
```julia; echo=false; results="hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
fig_size = (800, 600)
|
||||
|
||||
const frontmatter = (
|
||||
title = "Trigonometric functions",
|
||||
description = "Calculus with Julia: Trigonometric functions",
|
||||
@ -66,9 +69,8 @@ trigonometric functions are
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""Many students remember these through [SOH-CAH-TOA](http://mathworld.wolfram.com/SOHCAHTOA.html).""")
|
||||
```
|
||||
!!! note
|
||||
Many students remember these through [SOH-CAH-TOA](http://mathworld.wolfram.com/SOHCAHTOA.html).
|
||||
|
||||
Some algebra shows that $\tan(\theta) = \sin(\theta)/\cos(\theta)$. There are also ``3`` reciprocal functions, the cosecant, secant and cotangent.
|
||||
|
||||
@ -78,7 +80,6 @@ These definitions in terms of sides only apply for $0 \leq \theta \leq \pi/2$. M
|
||||
```julia; hold=true; echo=false; cache=true
|
||||
## {{{radian_to_trig}}}
|
||||
|
||||
fig_size = (400, 300)
|
||||
|
||||
function plot_angle(m)
|
||||
r = m*pi
|
||||
@ -181,15 +182,10 @@ sincos(pi/3)
|
||||
```
|
||||
|
||||
|
||||
```julia; echo=false
|
||||
note(L"""
|
||||
!!! note
|
||||
For really large values, round off error can play a big role. For example, the *exact* value of $\sin(1000000 \pi)$ is $0$, but the returned value is not quite $0$ `sin(1_000_000 * pi) = -2.231912181360871e-10`. For exact multiples of $\pi$ with large multiples the `sinpi` and `cospi` functions are useful.
|
||||
|
||||
For really large values, round off error can play a big role. For example, the *exact* value of $\sin(1000000 \pi)$ is $0$, but the returned value is not quite $0$ `sin(1_000_000 * pi) = -2.231912181360871e-10`. For exact multiples of $\pi$ with large multiples the `sinpi` and `cospi` functions are useful.
|
||||
|
||||
(Both functions are computed by first employing periodicity to reduce the problem to a smaller angle. However, for large multiples the floating-point roundoff becomes a problem with the usual functions.)
|
||||
|
||||
""")
|
||||
```
|
||||
(Both functions are computed by first employing periodicity to reduce the problem to a smaller angle. However, for large multiples the floating-point roundoff becomes a problem with the usual functions.)
|
||||
|
||||
##### Example
|
||||
|
||||
@ -356,7 +352,6 @@ end
|
||||
# create animoation
|
||||
b₁=1/3; n₁=3; b₂=1/4; n₂=4
|
||||
|
||||
fig_size = (400, 300)
|
||||
anim = @animate for t ∈ range(0, 2.5, length=50)
|
||||
makegraph(t, b₁, n₁, b₂, n₂)
|
||||
end
|
||||
@ -618,45 +613,47 @@ the unit *hyperbola* ($x^2 - y^2 = 1$). We define the hyperbolic
|
||||
sine ($\sinh$) and hyperbolic cosine ($\cosh$) through $(\cosh(\theta),
|
||||
\sinh(\theta)) = (x,y)$.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
## inspired by https://en.wikipedia.org/wiki/Hyperbolic_function
|
||||
# y^2 = x^2 - 1
|
||||
top(x) = sqrt(x^2 - 1)
|
||||
```julia; echo=false
|
||||
let
|
||||
## inspired by https://en.wikipedia.org/wiki/Hyperbolic_function
|
||||
# y^2 = x^2 - 1
|
||||
top(x) = sqrt(x^2 - 1)
|
||||
|
||||
p = plot(; legend=false, aspect_ratio=:equal)
|
||||
p = plot(; legend=false, aspect_ratio=:equal)
|
||||
|
||||
x₀ = 2
|
||||
xs = range(1, x₀, length=100)
|
||||
ys = top.(xs)
|
||||
plot!(p, xs, ys, color=:red)
|
||||
plot!(p, xs, -ys, color=:red)
|
||||
x₀ = 2
|
||||
xs = range(1, x₀, length=100)
|
||||
ys = top.(xs)
|
||||
plot!(p, xs, ys, color=:red)
|
||||
plot!(p, xs, -ys, color=:red)
|
||||
|
||||
xs = -reverse(xs)
|
||||
ys = top.(xs)
|
||||
plot!(p, xs, ys, color=:red)
|
||||
plot!(p, xs, -ys, color=:red)
|
||||
xs = -reverse(xs)
|
||||
ys = top.(xs)
|
||||
plot!(p, xs, ys, color=:red)
|
||||
plot!(p, xs, -ys, color=:red)
|
||||
|
||||
xs = range(-x₀, x₀, length=3)
|
||||
plot!(p, xs, xs, linestyle=:dash, color=:blue)
|
||||
plot!(p, xs, -xs, linestyle=:dash, color=:blue)
|
||||
xs = range(-x₀, x₀, length=3)
|
||||
plot!(p, xs, xs, linestyle=:dash, color=:blue)
|
||||
plot!(p, xs, -xs, linestyle=:dash, color=:blue)
|
||||
|
||||
a = 1.2
|
||||
plot!(p, [0,cosh(a)], [sinh(a), sinh(a)])
|
||||
annotate!(p, sinh(a)/2, sinh(a)+0.25,"cosh(a)")
|
||||
plot!(p, [cosh(a),cosh(a)], [sinh(a), 0])
|
||||
annotate!(p, sinh(a) + 1, cosh(a)/2,"sinh(a)")
|
||||
scatter!(p, [cosh(a)], [sinh(a)], markersize=5)
|
||||
a = 1.2
|
||||
plot!(p, [0,cosh(a)], [sinh(a), sinh(a)])
|
||||
annotate!(p, [(sinh(a)/2, sinh(a)+0.25,"cosh(a)")])
|
||||
plot!(p, [cosh(a),cosh(a)], [sinh(a), 0])
|
||||
annotate!(p, [(sinh(a) + 1, cosh(a)/2,"sinh(a)")])
|
||||
scatter!(p, [cosh(a)], [sinh(a)], markersize=5)
|
||||
|
||||
|
||||
ts = range(0, a, length=100)
|
||||
xs′ = cosh.(ts)
|
||||
ys′ = sinh.(ts)
|
||||
ts = range(0, a, length=100)
|
||||
xs′ = cosh.(ts)
|
||||
ys′ = sinh.(ts)
|
||||
|
||||
xs = [0, 1, xs′..., 0]
|
||||
ys = [0, 0, ys′..., 0]
|
||||
plot!(p, xs, ys, fillcolor=:red, fill=true, alpha=.3)
|
||||
xs = [0, 1, xs′..., 0]
|
||||
ys = [0, 0, ys′..., 0]
|
||||
plot!(p, xs, ys, fillcolor=:red, fill=true, alpha=.3)
|
||||
|
||||
p
|
||||
p
|
||||
end
|
||||
```
|
||||
|
||||
These values are more commonly expressed using the exponential function as:
|
||||
@ -682,8 +679,8 @@ What is bigger $\sin(1.23456)$ or $\cos(6.54321)$?
|
||||
```julia; hold=true; echo=false
|
||||
a = sin(1.23456) > cos(6.54321)
|
||||
choices = [raw"``\sin(1.23456)``", raw"``\cos(6.54321)``"]
|
||||
ans = a ? 1 : 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = a ? 1 : 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -694,8 +691,8 @@ Let $x=\pi/4$. What is bigger $\cos(x)$ or $x$?
|
||||
x = pi/4
|
||||
a = cos(x) > x
|
||||
choices = [raw"``\cos(x)``", "``x``"]
|
||||
ans = a ? 1 : 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = a ? 1 : 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -707,8 +704,8 @@ choices = [
|
||||
raw"``\cos(x) = \sin(x - \pi/2)``",
|
||||
raw"``\cos(x) = \sin(x + \pi/2)``",
|
||||
raw"``\cos(x) = \pi/2 \cdot \sin(x)``"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -720,8 +717,8 @@ choices = [
|
||||
L"The values $k\pi$ for $k$ in $\dots, -2, -1, 0, 1, 2, \dots$",
|
||||
L"The values $\pi/2 + k\pi$ for $k$ in $\dots, -2, -1, 0, 1, 2, \dots$",
|
||||
L"The values $2k\pi$ for $k$ in $\dots, -2, -1, 0, 1, 2, \dots$"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -768,24 +765,24 @@ The sine function is an *odd* function.
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["odd", "even", "neither"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
* The hyperbolic cosine is:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["odd", "even", "neither"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
* The hyperbolic tangent is:
|
||||
|
||||
```julia; hold=true; echo=false
|
||||
choices = ["odd", "even", "neither"]
|
||||
ans = 1
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 1
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
|
||||
@ -64,11 +64,9 @@ Variable names can be reused, as here, where we redefine `x`:
|
||||
x = 2
|
||||
```
|
||||
|
||||
```julia; echo=false
|
||||
note("""
|
||||
The `Pluto` interface for `Julia` is idiosyncratic, as variables are *reactive*. This interface allows changes to a variable `x` to propogate to all other cells referring to `x`. Consequently, the variable name can only be assigned *once* per notebook **unless** the name is in some other namespace, which can be arranged by including the assignment inside a function or a `let` block.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The `Pluto` interface for `Julia` is idiosyncratic, as variables are *reactive*. This interface allows changes to a variable `x` to propogate to all other cells referring to `x`. Consequently, the variable name can only be assigned *once* per notebook **unless** the name is in some other namespace, which can be arranged by including the assignment inside a function or a `let` block.
|
||||
|
||||
|
||||
|
||||
`Julia` is referred to as a "dynamic language" which means (in most
|
||||
@ -95,7 +93,7 @@ bottom = 5 - 6/7
|
||||
top/bottom
|
||||
```
|
||||
|
||||
#### Examples
|
||||
### Examples
|
||||
|
||||
##### Example
|
||||
|
||||
@ -197,27 +195,22 @@ the `Main` module. `Julia` looks for variables in this module when it
|
||||
encounters an expression and the value is substituted. Other uses, such as when variables are defined within a function, involve different contexts which may not be
|
||||
visible within the `Main` module.
|
||||
|
||||
```julia; echo=false;
|
||||
note("""
|
||||
The `varinfo` function will list the variables currently defined in the
|
||||
main workspace. There is no mechanism to delete a single variable.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The `varinfo` function will list the variables currently defined in the
|
||||
main workspace. There is no mechanism to delete a single variable.
|
||||
|
||||
```julia; echo=false;
|
||||
alert("""
|
||||
**Shooting oneselves in the foot.** `Julia` allows us to locally
|
||||
redefine variables that are built in, such as the value for `pi` or
|
||||
the function object assigned to `sin`. For example, this is a
|
||||
perfectly valid command `sin=3`. However, it will overwrite the
|
||||
typical value of `sin` so that `sin(3)` will be an error. At the terminal, the
|
||||
binding to `sin` occurs in the `Main` module. This shadows that
|
||||
value of `sin` bound in the `Base` module. Even if redefined in
|
||||
`Main`, the value in base can be used by fully qualifying the name,
|
||||
as in `Base.sin(pi)`. This uses the notation
|
||||
`module_name.variable_name` to look up a binding in a module.
|
||||
""")
|
||||
```
|
||||
!!! warning
|
||||
**Shooting oneselves in the foot.** `Julia` allows us to
|
||||
locally redefine variables that are built in, such as the value
|
||||
for `pi` or the function object assigned to `sin`. For example,
|
||||
this is a perfectly valid command `sin=3`. However, it will
|
||||
overwrite the typical value of `sin` so that `sin(3)` will be an
|
||||
error. At the terminal, the binding to `sin` occurs in the `Main`
|
||||
module. This shadows that value of `sin` bound in the `Base`
|
||||
module. Even if redefined in `Main`, the value in base can be used
|
||||
by fully qualifying the name, as in `Base.sin(pi)`. This uses the
|
||||
notation `module_name.variable_name` to look up a binding in a
|
||||
module.
|
||||
|
||||
## Variable names
|
||||
|
||||
@ -268,17 +261,12 @@ For example, we could have defined `theta` (`\theta[tab]`) and `v0` (`v\_0[tab]`
|
||||
θ = 45; v₀ = 200
|
||||
```
|
||||
|
||||
These notes often use Unicode alternatives to avoid the `Pluto` requirement of a single use of assigning to a variable name in a notebook without placing the assignment in a `let` block or a function body.
|
||||
!!! note "Unicode"
|
||||
These notes can be presented as HTML files *or* as `Pluto` notebooks. They often use Unicode alternatives to avoid the `Pluto` requirement of a single use of assigning to a variable name in a notebook without placing the assignment in a `let` block or a function body.
|
||||
|
||||
|
||||
```julia; echo=false;
|
||||
alert("""
|
||||
There is even support for tab-completion of
|
||||
[emojis](https://github.com/JuliaLang/julia/blob/master/stdlib/REPL/src/emoji_symbols.jl)
|
||||
such as `\\:snowman:[tab]` or `\\:koala:[tab]`
|
||||
|
||||
""")
|
||||
```
|
||||
!!! note "Emojis"
|
||||
There is even support for tab-completion of [emojis](https://github.com/JuliaLang/julia/blob/master/stdlib/REPL/src/emoji_symbols.jl) such as `\\:snowman:[tab]` or `\\:koala:[tab]`
|
||||
|
||||
##### Example
|
||||
|
||||
@ -404,8 +392,8 @@ What is the result of the above?
|
||||
p, q = 0.25, 0.2;
|
||||
top = p - q;
|
||||
bottom = sqrt(p*(1-p));
|
||||
ans = top/bottom;
|
||||
numericq(ans)
|
||||
answ = top/bottom;
|
||||
numericq(answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -433,8 +421,8 @@ q"some_really_long_name_that_is_no_fun_to_type",
|
||||
q"aMiXeDcAsEnAmE",
|
||||
q"fahrenheit451"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -445,8 +433,8 @@ Which of these symbols is one of `Julia`'s built-in math constants?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = [q"pi", q"oo", q"E", q"I"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -464,8 +452,8 @@ choices=[
|
||||
q"\delta[tab] = 1/10",
|
||||
q"delta[tab] = 1/10",
|
||||
q"$\\delta$ = 1/10"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -478,8 +466,8 @@ choices = [
|
||||
q"a=1, b=2, c=3",
|
||||
q"a,b,c = 1,2,3",
|
||||
q"a=1; b=2; c=3"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -497,6 +485,6 @@ choices = ["Assign all three variables at once to a value of `3`",
|
||||
"Create ``3`` linked values that will stay synced when any value changes",
|
||||
"Throw an error"
|
||||
]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
@ -8,7 +8,8 @@ using Plots
|
||||
using Measures
|
||||
using LaTeXStrings
|
||||
|
||||
fig_size = (400, 300)
|
||||
#fig_size = (400, 300)
|
||||
fig_size = (800, 600)
|
||||
|
||||
const frontmatter = (
|
||||
title = "Vectors",
|
||||
@ -463,23 +464,13 @@ component. However, the special keyword `end` will do so as well, when
|
||||
put into the context of indexing. So `v[end]` is more idiomatic. (Similarly, there is a `begin` keyword that is useful when the vector is not ``1``-based, as is typical but not mandatory.)
|
||||
|
||||
|
||||
```julia; echo=false;
|
||||
note("""
|
||||
There is [much more](http://julia.readthedocs.org/en/latest/manual/arrays/#indexing)
|
||||
to indexing than just indexing by a single integer value. For example, the following can be used for indexing:
|
||||
|
||||
* a scalar integer (as seen)
|
||||
|
||||
* a range
|
||||
|
||||
* a vector of integers
|
||||
|
||||
* a boolean vector
|
||||
|
||||
Some add-on packages extend this further.
|
||||
""",
|
||||
title="More on indexing", label="More on indexing")
|
||||
```
|
||||
!!! note "More on indexing"
|
||||
There is [much more](http://julia.readthedocs.org/en/latest/manual/arrays/#indexing) to indexing than just indexing by a single integer value. For example, the following can be used for indexing:
|
||||
* a scalar integer (as seen)
|
||||
* a range
|
||||
* a vector of integers
|
||||
* a boolean vector
|
||||
Some add-on packages extend this further.
|
||||
|
||||
### Assignment and indexing
|
||||
|
||||
@ -668,10 +659,9 @@ performant `abs2` function which, in general, efficiently finds $|x|^2$
|
||||
for various number types. The `.-` uses broadcasting to subtract a scalar (`mean(xs)`) from a vector (`xs`). Without the `.`, this would error.
|
||||
|
||||
|
||||
```julia; echo=false;
|
||||
note("""The `map` function is very much related to broadcasting and similarly named functions are found in many different programming languages. (The "dot" broadcast is mostly limited to `Julia` and mirrors on a similar usage of a dot in `MATLAB`.) For those familiar with other programming languages, using `map` may seem more natural. Its syntax is `map(f, xs)`.
|
||||
""")
|
||||
```
|
||||
!!! note
|
||||
The `map` function is very much related to broadcasting and similarly named functions are found in many different programming languages. (The "dot" broadcast is mostly limited to `Julia` and mirrors on a similar usage of a dot in `MATLAB`.) For those familiar with other programming languages, using `map` may seem more natural. Its syntax is `map(f, xs)`.
|
||||
|
||||
|
||||
### Comprehensions
|
||||
|
||||
@ -763,15 +753,9 @@ In the sequel, we will typically use broadcasting for this task using two
|
||||
steps: one to define a function the second to broadcast it.
|
||||
|
||||
|
||||
```julia; echo=false;
|
||||
note(L"""
|
||||
!!! note
|
||||
The style generally employed here is to use plural variable names for a collection of values, such as the vector of $y$ values and singular names when a single value is being referred to, leading to expressions like "`x in xs`".
|
||||
|
||||
The style generally employed here is to use plural variable names for a collection
|
||||
of values, such as the vector of $y$ values and singular names when a
|
||||
single value is being referred to, leading to expressions like "`x in xs`".
|
||||
|
||||
""")
|
||||
```
|
||||
|
||||
## Other container types
|
||||
|
||||
@ -805,8 +789,8 @@ q"v = {4, 3}",
|
||||
q"v = '4, 3'",
|
||||
q"v = (4,3)",
|
||||
q"v = <4,3>"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -815,8 +799,8 @@ Which command will create the vector with components "4,3,2,1"?
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = [q"v = [4,3,2,1]", q"v = (4,3,2,1)", q"v = {4,3,2,1}", q"v = '4, 3, 2, 1'", q"v = <4,3,2,1>"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -840,8 +824,8 @@ Which of the following is the unit vector in the direction of $\vec{v} = \langle
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = [q"[3, 4]", q"[0.6, 0.8]", q"[1.0, 1.33333]", q"[1, 1]"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -851,8 +835,8 @@ What vector is in the same direction as $\vec{v} = \langle 3,~ 4 \rangle$ but is
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = [q"[3, 4]", q"[30, 40]", q"[9.48683, 12.6491 ]", q"[10, 10]"]
|
||||
ans = 2
|
||||
radioq(choices, ans)
|
||||
answ = 2
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -861,8 +845,8 @@ If $\vec{v} = \langle 3,~ 4 \rangle$ and $\vec{w} = \langle 1,~ 2 \rangle$ find
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = [q"[4, 6]", q"[6, 8]", q"[11, 18]", q"[5, 10]"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -939,24 +923,24 @@ Express vector **c** in terms of **a** and **b**:
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = ["3a", "3b", "a + b", "a - b", "b-a"]
|
||||
ans = 1
|
||||
radioq(choices, ans)
|
||||
answ = 1
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Express vector **d** in terms of **a** and **b**:
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = ["3a", "3b", "a + b", "a - b", "b-a"]
|
||||
ans = 3
|
||||
radioq(choices, ans)
|
||||
answ = 3
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
Express vector **e** in terms of **a** and **b**:
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = ["3a", "3b", "a + b", "a - b", "b-a"]
|
||||
ans = 4
|
||||
radioq(choices, ans)
|
||||
answ = 4
|
||||
radioq(choices, answ)
|
||||
```
|
||||
|
||||
|
||||
@ -966,8 +950,8 @@ If `xs=[1, 2, 3, 4]` and `f(x) = x^2` which of these will not produce the vector
|
||||
|
||||
```julia; hold=true; echo=false;
|
||||
choices = [q"f.(xs)", q"map(f, xs)", q"[f(x) for x in xs]", "All three of them work"]
|
||||
ans = 4
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -982,8 +966,8 @@ What construct will give the function values of $f$ at the zeros of $g$?
|
||||
|
||||
```julia;hold=true; echo=false;
|
||||
choices = [q"sin(zs)", q"sin.(zs)", q"sin(.zs)", q".sin(zs)"]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
###### Question
|
||||
@ -997,6 +981,6 @@ q"sqrt.(zs)",
|
||||
q"zs^(1/2)",
|
||||
q"zs^(1./2)"
|
||||
]
|
||||
ans = 2
|
||||
radioq(choices, ans, keep_order=true)
|
||||
answ = 2
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
3
quarto/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/.quarto/
|
||||
/_site/
|
||||
/_book/
|
||||
10
quarto/ODEs/Project.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[deps]
|
||||
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
|
||||
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
|
||||
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
|
||||
MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca"
|
||||
NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56"
|
||||
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
|
||||
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
|
||||
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
|
||||
458
quarto/ODEs/differential_equations.qmd
Normal file
@ -0,0 +1,458 @@
|
||||
# The `DifferentialEquations` suite
|
||||
|
||||
|
||||
```{julia}
|
||||
#| echo: false
|
||||
|
||||
import Logging
|
||||
Logging.disable_logging(Logging.Info) # or e.g. Logging.Info
|
||||
Logging.disable_logging(Logging.Warn)
|
||||
|
||||
import SymPy
|
||||
function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject}
|
||||
println(io, "<span class=\"math-left-align\" style=\"padding-left: 4px; width:0; float:left;\"> ")
|
||||
println(io, "\\[")
|
||||
println(io, sympy.latex(x))
|
||||
println(io, "\\]")
|
||||
println(io, "</span>")
|
||||
end
|
||||
|
||||
# hack to work around issue
|
||||
import Markdown
|
||||
import CalculusWithJulia
|
||||
function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...)
|
||||
nm = joinpath("..", string(d), f)
|
||||
u = ""
|
||||
Markdown.parse(u)
|
||||
end
|
||||
|
||||
nothing
|
||||
```
|
||||
|
||||
This section uses these add-on packages:
|
||||
|
||||
|
||||
```{julia}
|
||||
using OrdinaryDiffEq
|
||||
using Plots
|
||||
using ModelingToolkit
|
||||
```
|
||||
|
||||
```{julia}
|
||||
#| echo: false
|
||||
#| results: "hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
const frontmatter = (
|
||||
title = "The `DifferentialEquations` suite",
|
||||
description = "Calculus with Julia: The `DifferentialEquations` suite",
|
||||
tags = ["CalculusWithJulia", "odes", "the `differentialequations` suite"],
|
||||
);
|
||||
fig_size = (800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
The [`DifferentialEquations`](https://github.com/SciML/DifferentialEquations.jl) suite of packages contains solvers for a wide range of various differential equations. This section just briefly touches touch on ordinary differential equations (ODEs), and so relies only on `OrdinaryDiffEq` part of the suite. For more detail on this type and many others covered by the suite of packages, there are many other resources, including the [documentation](https://diffeq.sciml.ai/stable/) and accompanying [tutorials](https://github.com/SciML/SciMLTutorials.jl).
|
||||
|
||||
|
||||
## SIR Model
|
||||
|
||||
|
||||
We follow along with an introduction to the SIR model for the spread of disease by [Smith and Moore](https://www.maa.org/press/periodicals/loci/joma/the-sir-model-for-spread-of-disease-introduction). This model received a workout due to the COVID-19 pandemic.
|
||||
|
||||
|
||||
The basic model breaks a population into three cohorts: The **susceptible** individuals, the **infected** individuals, and the **recovered** individuals. These add to the population size, $N$, which is fixed, but the cohort sizes vary in time. We name these cohort sizes $S(t)$, $I(t)$, and $R(t)$ and define $s(t)=S(t)/N$, $i(t) = I(t)/N$ and $r(t) = R(t)/N$ to be the respective proportions.
|
||||
|
||||
|
||||
The following *assumptions* are made about these cohorts by Smith and Moore:
|
||||
|
||||
|
||||
> No one is added to the susceptible group, since we are ignoring births and immigration. The only way an individual leaves the susceptible group is by becoming infected.
|
||||
|
||||
|
||||
|
||||
This implies the rate of change in time of $S(t)$ depends on the current number of susceptibles, and the amount of interaction with the infected cohorts. The model *assumes* each infected person has $b$ contacts per day that are sufficient to spread the disease. Not all contacts will be with susceptible people, but if people are assumed to mix within the cohorts, then there will be on average $b \cdot S(t)/N$ contacts with susceptible people per infected person. As each infected person is modeled identically, the time rate of change of $S(t)$ is:
|
||||
|
||||
|
||||
$$
|
||||
\frac{dS}{dt} = - b \cdot \frac{S(t)}{N} \cdot I(t) = -b \cdot s(t) \cdot I(t)
|
||||
$$
|
||||
|
||||
It is negative, as no one is added, only taken off. After dividing by $N$, this can also be expressed as $s'(t) = -b s(t) i(t)$.
|
||||
|
||||
|
||||
> assume that a fixed fraction $k$ of the infected group will recover during any given day.
|
||||
|
||||
|
||||
|
||||
This means the change in time of the recovered depends on $k$ and the number infected, giving rise to the equation
|
||||
|
||||
|
||||
$$
|
||||
\frac{dR}{dt} = k \cdot I(t)
|
||||
$$
|
||||
|
||||
which can also be expressed in proportions as $r'(t) = k \cdot i(t)$.
|
||||
|
||||
|
||||
Finally, from $S(t) + I(T) + R(t) = N$ we have $S'(T) + I'(t) + R'(t) = 0$ or $s'(t) + i'(t) + r'(t) = 0$.
|
||||
|
||||
|
||||
Combining, it is possible to express the rate of change of the infected population through:
|
||||
|
||||
|
||||
$$
|
||||
\frac{di}{dt} = b \cdot s(t) \cdot i(t) - k \cdot i(t)
|
||||
$$
|
||||
|
||||
The author's apply this model to flu statistics from Hong Kong where:
|
||||
|
||||
|
||||
$$
|
||||
\begin{align*}
|
||||
S(0) &= 7,900,000\\
|
||||
I(0) &= 10\\
|
||||
R(0) &= 0\\
|
||||
\end{align*}
|
||||
$$
|
||||
|
||||
In `Julia` we define these, `N` to model the total population, and `u0` to be the proportions.
|
||||
|
||||
|
||||
```{julia}
|
||||
S0, I0, R0 = 7_900_000, 10, 0
|
||||
N = S0 + I0 + R0
|
||||
u0 = [S0, I0, R0]/N # initial proportions
|
||||
```
|
||||
|
||||
An *estimated* set of values for $k$ and $b$ are $k=1/3$, coming from the average period of infectiousness being estimated at three days and $b=1/2$, which seems low in normal times, but not for an infected person who may be feeling quite ill and staying at home. (The model for COVID would certainly have a larger $b$ value).
|
||||
|
||||
|
||||
Okay, the mathematical modeling is done; now we try to solve for the unknown functions using `DifferentialEquations`.
|
||||
|
||||
|
||||
To warm up, if $b=0$ then $i'(t) = -k \cdot i(t)$ describes the infected. (There is no circulation of people in this case.) The solution would be achieved through:
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
k = 1/3
|
||||
|
||||
f(u,p,t) = -k * u # solving u′(t) = - k u(t)
|
||||
time_span = (0.0, 20.0)
|
||||
|
||||
prob = ODEProblem(f, I0/N, time_span)
|
||||
sol = solve(prob, Tsit5(), reltol=1e-8, abstol=1e-8)
|
||||
|
||||
plot(sol)
|
||||
```
|
||||
|
||||
The `sol` object is a set of numbers with a convenient `plot` method. As may have been expected, this graph shows exponential decay.
|
||||
|
||||
|
||||
A few comments are in order. The problem we want to solve is
|
||||
|
||||
|
||||
$$
|
||||
\frac{di}{dt} = -k \cdot i(t) = F(i(t), k, t)
|
||||
$$
|
||||
|
||||
where $F$ depends on the current value ($i$), a parameter ($k$), and the time ($t$). We did not utilize $p$ above for the parameter, as it was easy not to, but could have, and will in the following. The time variable $t$ does not appear by itself in our equation, so only `f(u, p, t) = -k * u` was used, `u` the generic name for a solution which in this case is $i$.
|
||||
|
||||
|
||||
The problem we set up needs an initial value (the $u0$) and a time span to solve over. Here we want time to model real time, so use floating point values.
|
||||
|
||||
|
||||
The plot shows steady decay, as there is no mixing of infected with others.
|
||||
|
||||
|
||||
Adding in the interaction requires a bit more work. We now have what is known as a *system* of equations:
|
||||
|
||||
|
||||
$$
|
||||
\begin{align*}
|
||||
\frac{ds}{dt} &= -b \cdot s(t) \cdot i(t)\\
|
||||
\frac{di}{dt} &= b \cdot s(t) \cdot i(t) - k \cdot i(t)\\
|
||||
\frac{dr}{dt} &= k \cdot i(t)\\
|
||||
\end{align*}
|
||||
$$
|
||||
|
||||
Systems of equations can be solved in a similar manner as a single ordinary differential equation, though adjustments are made to accommodate the multiple functions.
|
||||
|
||||
|
||||
We use a style that updates values in place, and note that `u` now holds $3$ different functions at once:
|
||||
|
||||
|
||||
```{julia}
|
||||
function sir!(du, u, p, t)
|
||||
k, b = p
|
||||
s, i, r = u[1], u[2], u[3]
|
||||
|
||||
ds = -b * s * i
|
||||
di = b * s * i - k * i
|
||||
dr = k * i
|
||||
|
||||
du[1], du[2], du[3] = ds, di, dr
|
||||
end
|
||||
```
|
||||
|
||||
The notation `du` is suggestive of both the derivative and a small increment. The mathematical formulation follows the derivative, the numeric solution uses a time step and increments the solution over this time step. The `Tsit5()` solver, used here, adaptively chooses a time step, `dt`; were the `Euler` method used, this time step would need to be explicit.
|
||||
|
||||
|
||||
:::{.callout-note}
|
||||
## Mutation not re-binding
|
||||
The `sir!` function has the trailing `!` indicating – by convention – it *mutates* its first value, `du`. In this case, through an assignment, as in `du[1]=ds`. This could use some explanation. The *binding* `du` refers to the *container* holding the $3$ values, whereas `du[1]` refers to the first value in that container. So `du[1]=ds` changes the first value, but not the *binding* of `du` to the container. That is, `du` mutates. This would be quite different were the call `du = [ds,di,dr]` which would create a new *binding* to a new container and not mutate the values in the original container.
|
||||
|
||||
:::
|
||||
|
||||
With the update function defined, the problem is setup and a solution found with in the same manner:
|
||||
|
||||
|
||||
```{julia}
|
||||
p = (k=1/3, b=1/2) # parameters
|
||||
time_span = (0.0, 150.0) # time span to solve over, 5 months
|
||||
|
||||
prob = ODEProblem(sir!, u0, time_span, p)
|
||||
sol = solve(prob, Tsit5())
|
||||
|
||||
plot(sol)
|
||||
plot!(x -> 0.5, linewidth=2) # mark 50% line
|
||||
```
|
||||
|
||||
The lower graph shows the number of infected at each day over the five-month period displayed. The peak is around 6-7% of the population at any one time. However, over time the recovered part of the population reaches over 50%, meaning more than half the population is modeled as getting sick.
|
||||
|
||||
|
||||
Now we change the parameter $b$ and observe the difference. We passed in a value `p` holding our two parameters, so we just need to change that and run the model again:
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
p = (k=1/2, b=2) # change b from 1/2 to 2 -- more daily contact
|
||||
prob = ODEProblem(sir!, u0, time_span, p)
|
||||
sol = solve(prob, Tsit5())
|
||||
|
||||
plot(sol)
|
||||
```
|
||||
|
||||
The graphs are somewhat similar, but the steady state is reached much more quickly and nearly everyone became infected.
|
||||
|
||||
|
||||
What about if $k$ were bigger?
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
p = (k=2/3, b=1/2)
|
||||
prob = ODEProblem(sir!, u0, time_span, p)
|
||||
sol = solve(prob, Tsit5())
|
||||
|
||||
plot(sol)
|
||||
```
|
||||
|
||||
The graphs show that under these conditions the infections never take off; we have $i' = (b\cdot s-k)i = k\cdot((b/k) s - 1) i$ which is always negative, since `(b/k)s < 1`, so infections will only decay.
|
||||
|
||||
|
||||
The solution object is indexed by time, then has the `s`, `i`, `r` estimates. We use this structure below to return the estimated proportion of recovered individuals at the end of the time span.
|
||||
|
||||
|
||||
```{julia}
|
||||
function recovered(k,b)
|
||||
prob = ODEProblem(sir!, u0, time_span, (k,b));
|
||||
sol = solve(prob, Tsit5());
|
||||
s,i,r = last(sol)
|
||||
r
|
||||
end
|
||||
```
|
||||
|
||||
This function makes it easy to see the impact of changing the parameters. For example, fixing $k=1/3$ we have:
|
||||
|
||||
|
||||
```{julia}
|
||||
f(b) = recovered(1/3, b)
|
||||
plot(f, 0, 2)
|
||||
```
|
||||
|
||||
This very clearly shows the sharp dependence on the value of $b$; below some level, the proportion of people who are ever infected (the recovered cohort) remains near $0$; above that level it can climb quickly towards $1$.
|
||||
|
||||
|
||||
The function `recovered` is of two variables returning a single value. In subsequent sections we will see a few $3$-dimensional plots that are common for such functions, here we skip ahead and show how to visualize multiple function plots at once using "`z`" values in a graph.
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
k, ks = 0.1, 0.2:0.1:0.9 # first `k` and then the rest
|
||||
bs = range(0, 2, length=100)
|
||||
zs = recovered.(k, bs) # find values for fixed k, each of bs
|
||||
p = plot(bs, k*one.(bs), zs, legend=false) # k*one.(ks) is [k,k,...,k]
|
||||
for k in ks
|
||||
plot!(p, bs, k*one.(bs), recovered.(k, bs))
|
||||
end
|
||||
p
|
||||
```
|
||||
|
||||
The 3-dimensional graph with `plotly` can have its viewing angle adjusted with the mouse. When looking down on the $x-y$ plane, which code `b` and `k`, we can see the rapid growth along a line related to $b/k$.
|
||||
|
||||
|
||||
Smith and Moore point out that $k$ is roughly the reciprocal of the number of days an individual is sick enough to infect others. This can be estimated during a breakout. However, they go on to note that there is no direct way to observe $b$, but there is an indirect way.
|
||||
|
||||
|
||||
The ratio $c = b/k$ is the number of close contacts per day times the number of days infected which is the number of close contacts per infected individual.
|
||||
|
||||
|
||||
This can be estimated from the curves once steady state has been reached (at the end of the pandemic).
|
||||
|
||||
|
||||
$$
|
||||
\frac{di}{ds} = \frac{di/dt}{ds/dt} = \frac{b \cdot s(t) \cdot i(t) - k \cdot i(t)}{-b \cdot s(t) \cdot i(t)} = -1 + \frac{1}{c \cdot s}
|
||||
$$
|
||||
|
||||
This equation does not depend on $t$; $s$ is the dependent variable. It could be solved numerically, but in this case affords an algebraic solution: $i = -s + (1/c) \log(s) + q$, where $q$ is some constant. The quantity $q = i + s - (1/c) \log(s)$ does not depend on time, so is the same at time $t=0$ as it is as $t \rightarrow \infty$. At $t=0$ we have $s(0) \approx 1$ and $i(0) \approx 0$, whereas $t \rightarrow \infty$, $i(t) \rightarrow 0$ and $s(t)$ goes to the steady state value, which can be estimated. Solving with $t=0$, we see $q=0 + 1 - (1/c)\log(1) = 1$. In the limit them $1 = 0 + s_{\infty} - (1/c)\log(s_\infty)$ or $c = \log(s_\infty)/(1-s_\infty)$.
|
||||
|
||||
|
||||
## Trajectory with drag
|
||||
|
||||
|
||||
We now solve numerically the problem of a trajectory with a drag force from air resistance.
|
||||
|
||||
|
||||
The general model is:
|
||||
|
||||
|
||||
$$
|
||||
\begin{align*}
|
||||
x''(t) &= - W(t,x(t), x'(t), y(t), y'(t)) \cdot x'(t)\\
|
||||
y''(t) &= -g - W(t,x(t), x'(t), y(t), y'(t)) \cdot y'(t)\\
|
||||
\end{align*}
|
||||
$$
|
||||
|
||||
with initial conditions: $x(0) = y(0) = 0$ and $x'(0) = v_0 \cos(\theta), y'(0) = v_0 \sin(\theta)$.
|
||||
|
||||
|
||||
This into an ODE by a standard trick. Here we define our function for updating a step. As can be seen the vector `u` contains both $\langle x,y \rangle$ and $\langle x',y' \rangle$
|
||||
|
||||
|
||||
```{julia}
|
||||
function xy!(du, u, p, t)
|
||||
g, γ = p.g, p.k
|
||||
x, y = u[1], u[2]
|
||||
x′, y′ = u[3], u[4] # unicode \prime[tab]
|
||||
|
||||
W = γ
|
||||
|
||||
du[1] = x′
|
||||
du[2] = y′
|
||||
du[3] = 0 - W * x′
|
||||
du[4] = -g - W * y′
|
||||
end
|
||||
```
|
||||
|
||||
This function $W$ is just a constant above, but can be easily modified as desired.
|
||||
|
||||
|
||||
:::{.callout-note}
|
||||
## A second-order ODE is a coupled first-order ODE
|
||||
The "standard" trick is to take a second order ODE like $u''(t)=u$ and turn this into two coupled ODEs by using a new name: $v=u'(t)$ and then $v'(t) = u(t)$. In this application, there are $4$ equations, as we have *both* $x''$ and $y''$ being so converted. The first and second components of $du$ are new variables, the third and fourth show the original equation.
|
||||
|
||||
:::
|
||||
|
||||
The initial conditions are specified through:
|
||||
|
||||
|
||||
```{julia}
|
||||
θ = pi/4
|
||||
v₀ = 200
|
||||
xy₀ = [0.0, 0.0]
|
||||
vxy₀ = v₀ * [cos(θ), sin(θ)]
|
||||
INITIAL = vcat(xy₀, vxy₀)
|
||||
```
|
||||
|
||||
The time span can be computed using an *upper* bound of no drag, for which the classic physics formulas give (when $y_0=0$) $(0, 2v_{y0}/g)$
|
||||
|
||||
|
||||
```{julia}
|
||||
g = 9.8
|
||||
TSPAN = (0, 2*vxy₀[2] / g)
|
||||
```
|
||||
|
||||
This allows us to define an `ODEProblem`:
|
||||
|
||||
|
||||
```{julia}
|
||||
trajectory_problem = ODEProblem(xy!, INITIAL, TSPAN)
|
||||
```
|
||||
|
||||
When $\gamma = 0$ there should be no drag and we expect to see a parabola:
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
ps = (g=9.8, k=0)
|
||||
SOL = solve(trajectory_problem, Tsit5(); p = ps)
|
||||
|
||||
plot(t -> SOL(t)[1], t -> SOL(t)[2], TSPAN...; legend=false)
|
||||
```
|
||||
|
||||
The plot is a parametric plot of the $x$ and $y$ parts of the solution over the time span. We can see the expected parabolic shape.
|
||||
|
||||
|
||||
On a *windy* day, the value of $k$ would be positive. Repeating the above with $k=1/4$ gives:
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
ps = (g=9.8, k=1/4)
|
||||
SOL = solve(trajectory_problem, Tsit5(); p = ps)
|
||||
|
||||
plot(t -> SOL(t)[1], t -> SOL(t)[2], TSPAN...; legend=false)
|
||||
```
|
||||
|
||||
We see that the $y$ values have gone negative. The `DifferentialEquations` package can adjust for that with a *callback* which terminates the problem once $y$ has gone negative. This can be implemented as follows:
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
condition(u,t,integrator) = u[2] # called when `u[2]` is negative
|
||||
affect!(integrator) = terminate!(integrator) # stop the process
|
||||
cb = ContinuousCallback(condition, affect!)
|
||||
|
||||
ps = (g=9.8, k = 1/4)
|
||||
SOL = solve(trajectory_problem, Tsit5(); p = ps, callback=cb)
|
||||
|
||||
plot(t -> SOL(t)[1], t -> SOL(t)[2], TSPAN...; legend=false)
|
||||
```
|
||||
|
||||
Finally, we note that the `ModelingToolkit` package provides symbolic-numeric computing. This allows the equations to be set up symbolically, as in `SymPy` before being passed off to `DifferentialEquations` to solve numerically. The above example with no wind resistance could be translated into the following:
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
@parameters t γ g
|
||||
@variables x(t) y(t)
|
||||
D = Differential(t)
|
||||
|
||||
eqs = [D(D(x)) ~ -γ * D(x),
|
||||
D(D(y)) ~ -g - γ * D(y)]
|
||||
|
||||
@named sys = ODESystem(eqs)
|
||||
sys = ode_order_lowering(sys) # turn 2nd order into 1st
|
||||
|
||||
u0 = [D(x) => vxy₀[1],
|
||||
D(y) => vxy₀[2],
|
||||
x => 0.0,
|
||||
y => 0.0]
|
||||
|
||||
p = [γ => 0.0,
|
||||
g => 9.8]
|
||||
|
||||
prob = ODEProblem(sys, u0, TSPAN, p, jac=true)
|
||||
sol = solve(prob,Tsit5())
|
||||
|
||||
plot(t -> sol(t)[3], t -> sol(t)[4], TSPAN..., legend=false)
|
||||
```
|
||||
|
||||
The toolkit will automatically generate fast functions and can perform transformations (such as is done by `ode_order_lowering`) before passing along to the numeric solves.
|
||||
|
||||
|
||||
845
quarto/ODEs/euler.qmd
Normal file
@ -0,0 +1,845 @@
|
||||
# Euler's method
|
||||
|
||||
|
||||
```{julia}
|
||||
#| echo: false
|
||||
|
||||
import Logging
|
||||
Logging.disable_logging(Logging.Info) # or e.g. Logging.Info
|
||||
Logging.disable_logging(Logging.Warn)
|
||||
|
||||
import SymPy
|
||||
function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject}
|
||||
println(io, "<span class=\"math-left-align\" style=\"padding-left: 4px; width:0; float:left;\"> ")
|
||||
println(io, "\\[")
|
||||
println(io, sympy.latex(x))
|
||||
println(io, "\\]")
|
||||
println(io, "</span>")
|
||||
end
|
||||
|
||||
# hack to work around issue
|
||||
import Markdown
|
||||
import CalculusWithJulia
|
||||
function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...)
|
||||
nm = joinpath("..", string(d), f)
|
||||
u = ""
|
||||
Markdown.parse(u)
|
||||
end
|
||||
|
||||
nothing
|
||||
```
|
||||
|
||||
This section uses these add-on packages:
|
||||
|
||||
|
||||
```{julia}
|
||||
using CalculusWithJulia
|
||||
using Plots
|
||||
using SymPy
|
||||
using Roots
|
||||
```
|
||||
|
||||
```{julia}
|
||||
#| echo: false
|
||||
#| results: "hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
|
||||
const frontmatter = (
|
||||
title = "Euler's method",
|
||||
description = "Calculus with Julia: Euler's method",
|
||||
tags = ["CalculusWithJulia", "odes", "euler's method"],
|
||||
);
|
||||
fig_size = (800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
The following section takes up the task of numerically approximating solutions to differential equations. `Julia` has a huge set of state-of-the-art tools for this task starting with the [DifferentialEquations](https://github.com/SciML/DifferentialEquations.jl) package. We don't use that package in this section, focusing on simpler methods and implementations for pedagogical purposes, but any further exploration should utilize the tools provided therein. A brief introduction to the package follows in an upcoming [section](./differential_equations.html).
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
Consider the differential equation:
|
||||
|
||||
|
||||
$$
|
||||
y'(x) = y(x) \cdot x, \quad y(1)=1,
|
||||
$$
|
||||
|
||||
which can be solved with `SymPy`:
|
||||
|
||||
|
||||
```{julia}
|
||||
@syms x, y, u()
|
||||
D = Differential(x)
|
||||
x0, y0 = 1, 1
|
||||
F(y,x) = y*x
|
||||
|
||||
dsolve(D(u)(x) - F(u(x), x))
|
||||
```
|
||||
|
||||
With the given initial condition, the solution becomes:
|
||||
|
||||
|
||||
```{julia}
|
||||
out = dsolve(D(u)(x) - F(u(x),x), u(x), ics=Dict(u(x0) => y0))
|
||||
```
|
||||
|
||||
Plotting this solution over the slope field
|
||||
|
||||
|
||||
```{julia}
|
||||
p = plot(legend=false)
|
||||
vectorfieldplot!((x,y) -> [1, F(x,y)], xlims=(0, 2.5), ylims=(0, 10))
|
||||
plot!(rhs(out), linewidth=5)
|
||||
```
|
||||
|
||||
we see that the vectors that are drawn seem to be tangent to the graph of the solution. This is no coincidence, the tangent lines to integral curves are in the direction of the slope field.
|
||||
|
||||
|
||||
What if the graph of the solution were not there, could we use this fact to *approximately* reconstruct the solution?
|
||||
|
||||
|
||||
That is, if we stitched together pieces of the slope field, would we get a curve that was close to the actual answer?
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
#| cache: true
|
||||
## {{{euler_graph}}}
|
||||
function make_euler_graph(n)
|
||||
x, y = symbols("x, y")
|
||||
F(y,x) = y*x
|
||||
x0, y0 = 1, 1
|
||||
|
||||
h = (2-1)/5
|
||||
xs = zeros(n+1)
|
||||
ys = zeros(n+1)
|
||||
xs[1] = x0 # index is off by 1
|
||||
ys[1] = y0
|
||||
for i in 1:n
|
||||
xs[i + 1] = xs[i] + h
|
||||
ys[i + 1] = ys[i] + h * F(ys[i], xs[i])
|
||||
end
|
||||
|
||||
p = plot(legend=false)
|
||||
vectorfieldplot!((x,y) -> [1, F(y,x)], xlims=(1,2), ylims=(0,6))
|
||||
|
||||
## Add Euler soln
|
||||
plot!(p, xs, ys, linewidth=5)
|
||||
scatter!(p, xs, ys)
|
||||
|
||||
## add function
|
||||
out = dsolve(u'(x) - F(u(x), x), u(x), ics=(u, x0, y0))
|
||||
plot!(p, rhs(out), x0, xs[end], linewidth=5)
|
||||
|
||||
p
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
n = 5
|
||||
anim = @animate for i=1:n
|
||||
make_euler_graph(i)
|
||||
end
|
||||
|
||||
imgfile = tempname() * ".gif"
|
||||
gif(anim, imgfile, fps = 1)
|
||||
|
||||
|
||||
caption = """
|
||||
Illustration of a function stitching together slope field lines to
|
||||
approximate the answer to an initial-value problem. The other function drawn is the actual solution.
|
||||
"""
|
||||
|
||||
ImageFile(imgfile, caption)
|
||||
```
|
||||
|
||||
The illustration suggests the answer is yes, let's see. The solution is drawn over $x$ values $1$ to $2$. Let's try piecing together $5$ pieces between $1$ and $2$ and see what we have.
|
||||
|
||||
|
||||
The slope-field vectors are *scaled* versions of the vector `[1, F(y,x)]`. The `1` is the part in the direction of the $x$ axis, so here we would like that to be $0.2$ (which is $(2-1)/5$. So our vectors would be `0.2 * [1, F(y,x)]`. To allow for generality, we use `h` in place of the specific value $0.2$.
|
||||
|
||||
|
||||
Then our first pieces would be the line connecting $(x_0,y_0)$ to
|
||||
|
||||
|
||||
$$
|
||||
\langle x_0, y_0 \rangle + h \cdot \langle 1, F(y_0, x_0) \rangle.
|
||||
$$
|
||||
|
||||
The above uses vector notation to add the piece scaled by $h$ to the starting point. Rather than continue with that notation, we will use subscripts. Let $x_1$, $y_1$ be the postion of the tip of the vector. Then we have:
|
||||
|
||||
|
||||
$$
|
||||
x_1 = x_0 + h, \quad y_1 = y_0 + h F(y_0, x_0).
|
||||
$$
|
||||
|
||||
With this notation, it is easy to see what comes next:
|
||||
|
||||
|
||||
$$
|
||||
x_2 = x_1 + h, \quad y_2 = y_1 + h F(y_1, x_1).
|
||||
$$
|
||||
|
||||
We just shifted the indices forward by $1$. But graphically what is this? It takes the tip of the first part of our "stitched" together solution, finds the slope filed there (`[1, F(y,x)]`) and then uses this direction to stitch together one more piece.
|
||||
|
||||
|
||||
Clearly, we can repeat. The $n$th piece will end at:
|
||||
|
||||
|
||||
$$
|
||||
x_{n+1} = x_n + h, \quad y_{n+1} = y_n + h F(y_n, x_n).
|
||||
$$
|
||||
|
||||
For our example, we can do some numerics. We want $h=0.2$ and $5$ pieces, so values of $y$ at $x_0=1, x_1=1.2, x_2=1.4, x_3=1.6, x_4=1.8,$ and $x_5=2$.
|
||||
|
||||
|
||||
Below we do this in a loop. We have to be a bit careful, as in `Julia` the vector of zeros we create to store our answers begins indexing at $1$, and not $0$.
|
||||
|
||||
|
||||
```{julia}
|
||||
n=5
|
||||
h = (2-1)/n
|
||||
xs = zeros(n+1)
|
||||
ys = zeros(n+1)
|
||||
xs[1] = x0 # index is off by 1
|
||||
ys[1] = y0
|
||||
for i in 1:n
|
||||
xs[i + 1] = xs[i] + h
|
||||
ys[i + 1] = ys[i] + h * F(ys[i], xs[i])
|
||||
end
|
||||
```
|
||||
|
||||
So how did we do? Let's look graphically:
|
||||
|
||||
|
||||
```{julia}
|
||||
plot(exp(-1/2)*exp(x^2/2), x0, 2)
|
||||
plot!(xs, ys)
|
||||
```
|
||||
|
||||
Not bad. We wouldn't expect this to be exact - due to the concavity of the solution, each step is an underestimate. However, we see it is an okay approximation and would likely be better with a smaller $h$. A topic we pursue in just a bit.
|
||||
|
||||
|
||||
Rather than type in the above command each time, we wrap it all up in a function. The inputs are $n$, $a=x_0$, $b=x_n$, $y_0$, and, most importantly, $F$. The output is massaged into a function through a call to `linterp`, rather than two vectors. The `linterp` function we define below just finds a function that linearly interpolates between the points and is `NaN` outside of the range of the $x$ values:
|
||||
|
||||
|
||||
```{julia}
|
||||
function linterp(xs, ys)
|
||||
function(x)
|
||||
((x < xs[1]) || (x > xs[end])) && return NaN
|
||||
for i in 1:(length(xs) - 1)
|
||||
if xs[i] <= x < xs[i+1]
|
||||
l = (x-xs[i]) / (xs[i+1] - xs[i])
|
||||
return (1-l) * ys[i] + l * ys[i+1]
|
||||
end
|
||||
end
|
||||
ys[end]
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
With that, here is our function to find an approximate solution to $y'=F(y,x)$ with initial condition:
|
||||
|
||||
|
||||
```{julia}
|
||||
function euler(F, x0, xn, y0, n)
|
||||
h = (xn - x0)/n
|
||||
xs = zeros(n+1)
|
||||
ys = zeros(n+1)
|
||||
xs[1] = x0
|
||||
ys[1] = y0
|
||||
for i in 1:n
|
||||
xs[i + 1] = xs[i] + h
|
||||
ys[i + 1] = ys[i] + h * F(ys[i], xs[i])
|
||||
end
|
||||
linterp(xs, ys)
|
||||
end
|
||||
```
|
||||
|
||||
With `euler`, it becomes easy to explore different values.
|
||||
|
||||
|
||||
For example, we thought the solution would look better with a smaller $h$ (or larger $n$). Instead of $n=5$, let's try $n=50$:
|
||||
|
||||
|
||||
```{julia}
|
||||
u₁₂ = euler(F, 1, 2, 1, 50)
|
||||
plot(exp(-1/2)*exp(x^2/2), x0, 2)
|
||||
plot!(u₁₂, x0, 2)
|
||||
```
|
||||
|
||||
It is more work for the computer, but not for us, and clearly a much better approximation to the actual answer is found.
|
||||
|
||||
|
||||
## The Euler method
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
imgfile ="figures/euler.png"
|
||||
caption = """
|
||||
Figure from first publication of Euler's method. From [Gander and Wanner](http://www.unige.ch/~gander/Preprints/Ritz.pdf).
|
||||
"""
|
||||
|
||||
ImageFile(:ODEs, imgfile, caption)
|
||||
```
|
||||
|
||||
The name of our function reflects the [mathematician](https://en.wikipedia.org/wiki/Leonhard_Euler) associated with the iteration:
|
||||
|
||||
|
||||
$$
|
||||
x_{n+1} = x_n + h, \quad y_{n+1} = y_n + h \cdot F(y_n, x_n),
|
||||
$$
|
||||
|
||||
to approximate a solution to the first-order, ordinary differential equation with initial values: $y'(x) = F(y,x)$.
|
||||
|
||||
|
||||
[The Euler method](https://en.wikipedia.org/wiki/Euler_method) uses linearization. Each "step" is just an approximation of the function value $y(x_{n+1})$ with the value from the tangent line tangent to the point $(x_n, y_n)$.
|
||||
|
||||
|
||||
Each step introduces an error. The error in one step is known as the *local truncation error* and can be shown to be about equal to $1/2 \cdot h^2 \cdot f''(x_{n})$ assuming $y$ has $3$ or more derivatives.
|
||||
|
||||
|
||||
The total error, or more commonly, *global truncation error*, is the error between the actual answer and the approximate answer at the end of the process. It reflects an accumulation of these local errors. This error is *bounded* by a constant times $h$. Since it gets smaller as $h$ gets smaller in direct proportion, the Euler method is called *first order*.
|
||||
|
||||
|
||||
Other, somewhat more complicated, methods have global truncation errors that involve higher powers of $h$ - that is for the same size $h$, the error is smaller. In analogy is the fact that Riemann sums have error that depends on $h$, whereas other methods of approximating the integral have smaller errors. For example, Simpson's rule had error related to $h^4$. So, the Euler method may not be employed if there is concern about total resources (time, computer, ...), it is important for theoretical purposes in a manner similar to the role of the Riemann integral.
|
||||
|
||||
|
||||
In the examples, we will see that for many problems the simple Euler method is satisfactory, but not always so. The task of numerically solving differential equations is not a one-size-fits-all one. In the following, a few different modifications are presented to the basic Euler method, but this just scratches the surface of the topic.
|
||||
|
||||
|
||||
#### Examples
|
||||
|
||||
|
||||
##### Example
|
||||
|
||||
|
||||
Consider the initial value problem $y'(x) = x + y(x)$ with initial condition $y(0)=1$. This problem can be solved exactly. Here we approximate over $[0,2]$ using Euler's method.
|
||||
|
||||
|
||||
```{julia}
|
||||
𝑭(y,x) = x + y
|
||||
𝒙0, 𝒙n, 𝒚0 = 0, 2, 1
|
||||
𝒇 = euler(𝑭, 𝒙0, 𝒙n, 𝒚0, 25)
|
||||
𝒇(𝒙n)
|
||||
```
|
||||
|
||||
We graphically compare our approximate answer with the exact one:
|
||||
|
||||
|
||||
```{julia}
|
||||
plot(𝒇, 𝒙0, 𝒙n)
|
||||
𝒐ut = dsolve(D(u)(x) - 𝑭(u(x),x), u(x), ics = Dict(u(𝒙0) => 𝒚0))
|
||||
plot(rhs(𝒐ut), 𝒙0, 𝒙n)
|
||||
plot!(𝒇, 𝒙0, 𝒙n)
|
||||
```
|
||||
|
||||
From the graph it appears our value for `f(xn)` will underestimate the actual value of the solution slightly.
|
||||
|
||||
|
||||
##### Example
|
||||
|
||||
|
||||
The equation $y'(x) = \sin(x \cdot y)$ is not separable, so need not have an easy solution. The default method will fail. Looking at the available methods with `sympy.classify_ode(𝐞qn, u(x))` shows a power series method which can return a power series *approximation* (a Taylor polynomial). Let's look at comparing an approximate answer given by the Euler method to that one returned by `SymPy`.
|
||||
|
||||
|
||||
First, the `SymPy` solution:
|
||||
|
||||
|
||||
```{julia}
|
||||
𝐅(y,x) = sin(x*y)
|
||||
𝐞qn = D(u)(x) - 𝐅(u(x), x)
|
||||
𝐨ut = dsolve(𝐞qn, hint="1st_power_series")
|
||||
```
|
||||
|
||||
If we assume $y(0) = 1$, we can continue:
|
||||
|
||||
|
||||
```{julia}
|
||||
𝐨ut1 = dsolve(𝐞qn, u(x), ics=Dict(u(0) => 1), hint="1st_power_series")
|
||||
```
|
||||
|
||||
The approximate value given by the Euler method is
|
||||
|
||||
|
||||
```{julia}
|
||||
𝐱0, 𝐱n, 𝐲0 = 0, 2, 1
|
||||
|
||||
plot(legend=false)
|
||||
vectorfieldplot!((x,y) -> [1, 𝐅(y,x)], xlims=(𝐱0, 𝐱n), ylims=(0,5))
|
||||
plot!(rhs(𝐨ut1).removeO(), linewidth=5)
|
||||
|
||||
𝐮 = euler(𝐅, 𝐱0, 𝐱n, 𝐲0, 10)
|
||||
plot!(𝐮, linewidth=5)
|
||||
```
|
||||
|
||||
We see that the answer found from using a polynomial series matches that of Euler's method for a bit, but as time evolves, the approximate solution given by Euler's method more closely tracks the slope field.
|
||||
|
||||
|
||||
##### Example
|
||||
|
||||
|
||||
The [Brachistochrone problem](http://www.unige.ch/~gander/Preprints/Ritz.pdf) was posed by Johann Bernoulli in 1696. It asked for the curve between two points for which an object will fall faster along that curve than any other. For an example, a bead sliding on a wire will take a certain amount of time to get from point $A$ to point $B$, the time depending on the shape of the wire. Which shape will take the least amount of time?
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
imgfile = "figures/bead-game.jpg"
|
||||
caption = """
|
||||
|
||||
A child's bead game. What shape wire will produce the shortest time for a bed to slide from a top to the bottom?
|
||||
|
||||
"""
|
||||
ImageFile(:ODEs, imgfile, caption)
|
||||
```
|
||||
|
||||
Restrict our attention to the $x$-$y$ plane, and consider a path, between the point $(0,A)$ and $(B,0)$. Let $y(x)$ be the distance from $A$, so $y(0)=0$ and at the end $y$ will be $A$.
|
||||
|
||||
|
||||
[Galileo](http://www-history.mcs.st-and.ac.uk/HistTopics/Brachistochrone.html) knew the straight line was not the curve, but incorrectly thought the answer was a part of a circle.
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
imgfile = "figures/galileo.gif"
|
||||
caption = """
|
||||
As early as 1638, Galileo showed that an object falling along `AC` and then `CB` will fall faster than one traveling along `AB`, where `C` is on the arc of a circle.
|
||||
From the [History of Math Archive](http://www-history.mcs.st-and.ac.uk/HistTopics/Brachistochrone.html).
|
||||
"""
|
||||
ImageFile(:ODEs, imgfile, caption)
|
||||
```
|
||||
|
||||
This simulation also suggests that a curved path is better than the shorter straight one:
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
#| cache: true
|
||||
##{{{brach_graph}}}
|
||||
|
||||
function brach(f, x0, vx0, y0, vy0, dt, n)
|
||||
m = 1
|
||||
g = 9.8
|
||||
|
||||
axs = Float64[0]
|
||||
ays = Float64[-g]
|
||||
vxs = Float64[vx0]
|
||||
vys = Float64[vy0]
|
||||
xs = Float64[x0]
|
||||
ys = Float64[y0]
|
||||
|
||||
for i in 1:n
|
||||
x = xs[end]
|
||||
vx = vxs[end]
|
||||
|
||||
ax = -f'(x) * (f''(x) * vx^2 + g) / (1 + f'(x)^2)
|
||||
ay = f''(x) * vx^2 + f'(x) * ax
|
||||
|
||||
push!(axs, ax)
|
||||
push!(ays, ay)
|
||||
|
||||
push!(vxs, vx + ax * dt)
|
||||
push!(vys, vys[end] + ay * dt)
|
||||
push!(xs, x + vxs[end] * dt)# + (1/2) * ax * dt^2)
|
||||
push!(ys, ys[end] + vys[end] * dt)# + (1/2) * ay * dt^2)
|
||||
end
|
||||
|
||||
[xs ys vxs vys axs ays]
|
||||
|
||||
end
|
||||
|
||||
|
||||
fs = [x -> 1 - x,
|
||||
x -> (x-1)^2,
|
||||
x -> 1 - sqrt(1 - (x-1)^2),
|
||||
x -> - (x-1)*(x+1),
|
||||
x -> 3*(x-1)*(x-1/3)
|
||||
]
|
||||
|
||||
|
||||
MS = [brach(f, 1/100, 0, 1, 0, 1/100, 100) for f in fs]
|
||||
|
||||
|
||||
function make_brach_graph(n)
|
||||
|
||||
p = plot(xlim=(0,1), ylim=(-1/3, 1), legend=false)
|
||||
for (i,f) in enumerate(fs)
|
||||
plot!(f, 0, 1)
|
||||
U = MS[i]
|
||||
x = min(1.0, U[n,1])
|
||||
scatter!(p, [x], [f(x)])
|
||||
end
|
||||
p
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
n = 4
|
||||
anim = @animate for i=[1,5,10,15,20,25,30,35,40,45,50,55,60]
|
||||
make_brach_graph(i)
|
||||
end
|
||||
|
||||
imgfile = tempname() * ".gif"
|
||||
gif(anim, imgfile, fps = 1)
|
||||
|
||||
|
||||
caption = """
|
||||
The race is on. An illustration of beads falling along a path, as can be seen, some paths are faster than others. The fastest path would follow a cycloid. See [Bensky and Moelter](https://pdfs.semanticscholar.org/66c1/4d8da6f2f5f2b93faf4deb77aafc7febb43a.pdf) for details on simulating a bead on a wire.
|
||||
"""
|
||||
|
||||
ImageFile(imgfile, caption)
|
||||
```
|
||||
|
||||
Now, the natural question is which path is best? The solution can be [reduced](http://mathworld.wolfram.com/BrachistochroneProblem.html) to solving this equation for a positive $c$:
|
||||
|
||||
|
||||
$$
|
||||
1 + (y'(x))^2 = \frac{c}{y}, \quad c > 0.
|
||||
$$
|
||||
|
||||
Reexpressing, this becomes:
|
||||
|
||||
|
||||
$$
|
||||
\frac{dy}{dx} = \sqrt{\frac{C-y}{y}}.
|
||||
$$
|
||||
|
||||
This is a separable equation and can be solved, but even `SymPy` has trouble with this integral. However, the result has been known to be a piece of a cycloid since the insightful Jacob Bernoulli used an analogy from light bending to approach the problem. The answer is best described parametrically through:
|
||||
|
||||
|
||||
$$
|
||||
x(u) = c\cdot u - \frac{c}{2}\sin(2u), \quad y(u) = \frac{c}{2}( 1- \cos(2u)), \quad 0 \leq u \leq U.
|
||||
$$
|
||||
|
||||
The values of $U$ and $c$ must satisfy $(x(U), y(U)) = (B, A)$.
|
||||
|
||||
|
||||
Rather than pursue this, we will solve it numerically for a fixed value of $C$ over a fixed interval to see the shape.
|
||||
|
||||
|
||||
The equation can be written in terms of $y'=F(y,x)$, where
|
||||
|
||||
|
||||
$$
|
||||
F(y,x) = \sqrt{\frac{c-y}{y}}.
|
||||
$$
|
||||
|
||||
But as $y_0 = 0$, we immediately would have a problem with the first step, as there would be division by $0$.
|
||||
|
||||
|
||||
This says that for the optimal solution, the bead picks up speed by first sliding straight down before heading off towards $B$. That's great for the physics, but runs roughshod over our Euler method, as the first step has an infinity.
|
||||
|
||||
|
||||
For this, we can try the *backwards Euler* method which uses the slope at $(x_{n+1}, y_{n+1})$, rather than $(x_n, y_n)$. The update step becomes:
|
||||
|
||||
|
||||
$$
|
||||
y_{n+1} = y_n + h \cdot F(y_{n+1}, x_{n+1}).
|
||||
$$
|
||||
|
||||
Seems innocuous, but the value we are trying to find, $y_{n+1}$, is now on both sides of the equation, so is only *implicitly* defined. In this code, we use the `find_zero` function from the `Roots` package. The caveat is, this function needs a good initial guess, and the one we use below need not be widely applicable.
|
||||
|
||||
|
||||
```{julia}
|
||||
function back_euler(F, x0, xn, y0, n)
|
||||
h = (xn - x0)/n
|
||||
xs = zeros(n+1)
|
||||
ys = zeros(n+1)
|
||||
xs[1] = x0
|
||||
ys[1] = y0
|
||||
for i in 1:n
|
||||
xs[i + 1] = xs[i] + h
|
||||
## solve y[i+1] = y[i] + h * F(y[i+1], x[i+1])
|
||||
ys[i + 1] = find_zero(y -> ys[i] + h * F(y, xs[i + 1]) - y, ys[i]+h)
|
||||
end
|
||||
linterp(xs, ys)
|
||||
end
|
||||
```
|
||||
|
||||
We then have with $C=1$ over the interval $[0,1.2]$ the following:
|
||||
|
||||
|
||||
```{julia}
|
||||
𝐹(y, x; C=1) = sqrt(C/y - 1)
|
||||
𝑥0, 𝑥n, 𝑦0 = 0, 1.2, 0
|
||||
cyc = back_euler(𝐹, 𝑥0, 𝑥n, 𝑦0, 50)
|
||||
plot(x -> 1 - cyc(x), 𝑥0, 𝑥n)
|
||||
```
|
||||
|
||||
Remember, $y$ is the displacement from the top, so it is non-negative. Above we flipped the graph to make it look more like expectation. In general, the trajectory may actually dip below the ending point and come back up. The above won't see this, for as written $dy/dx \geq 0$, which need not be the case, as the defining equation is in terms of $(dy/dx)^2$, so the derivative could have any sign.
|
||||
|
||||
|
||||
##### Example: stiff equations
|
||||
|
||||
|
||||
The Euler method is *convergent*, in that as $h$ goes to $0$, the approximate solution will converge to the actual answer. However, this does not say that for a fixed size $h$, the approximate value will be good. For example, consider the differential equation $y'(x) = -5y$. This has solution $y(x)=y_0 e^{-5x}$. However, if we try the Euler method to get an answer over $[0,2]$ with $h=0.5$ we don't see this:
|
||||
|
||||
|
||||
```{julia}
|
||||
ℱ(y,x) = -5y
|
||||
𝓍0, 𝓍n, 𝓎0 = 0, 2, 1
|
||||
𝓊 = euler(ℱ, 𝓍0, 𝓍n, 𝓎0, 4) # n =4 => h = 2/4
|
||||
vectorfieldplot((x,y) -> [1, ℱ(y,x)], xlims=(0, 2), ylims=(-5, 5))
|
||||
plot!(x -> y0 * exp(-5x), 0, 2, linewidth=5)
|
||||
plot!(𝓊, 0, 2, linewidth=5)
|
||||
```
|
||||
|
||||
What we see is that the value of $h$ is too big to capture the decay scale of the solution. A smaller $h$, can do much better:
|
||||
|
||||
|
||||
```{julia}
|
||||
𝓊₁ = euler(ℱ, 𝓍0, 𝓍n, 𝓎0, 50) # n=50 => h = 2/50
|
||||
plot(x -> y0 * exp(-5x), 0, 2)
|
||||
plot!(𝓊₁, 0, 2)
|
||||
```
|
||||
|
||||
This is an example of a [stiff equation](https://en.wikipedia.org/wiki/Stiff_equation). Such equations cause explicit methods like the Euler one problems, as small $h$s are needed to good results.
|
||||
|
||||
|
||||
The implicit, backward Euler method does not have this issue, as we can see here:
|
||||
|
||||
|
||||
```{julia}
|
||||
𝓊₂ = back_euler(ℱ, 𝓍0, 𝓍n, 𝓎0, 4) # n =4 => h = 2/4
|
||||
vectorfieldplot((x,y) -> [1, ℱ(y,x)], xlims=(0, 2), ylims=(-1, 1))
|
||||
plot!(x -> y0 * exp(-5x), 0, 2, linewidth=5)
|
||||
plot!(𝓊₂, 0, 2, linewidth=5)
|
||||
```
|
||||
|
||||
##### Example: The pendulum
|
||||
|
||||
|
||||
The differential equation describing the simple pendulum is
|
||||
|
||||
|
||||
$$
|
||||
\theta''(t) = - \frac{g}{l}\sin(\theta(t)).
|
||||
$$
|
||||
|
||||
The typical approach to solving for $\theta(t)$ is to use the small-angle approximation that $\sin(x) \approx x$, and then the differential equation simplifies to: $\theta''(t) = -g/l \cdot \theta(t)$, which is easily solved.
|
||||
|
||||
|
||||
Here we try to get an answer numerically. However, the problem, as stated, is not a first order equation due to the $\theta''(t)$ term. If we let $u(t) = \theta(t)$ and $v(t) = \theta'(t)$, then we get *two* coupled first order equations:
|
||||
|
||||
|
||||
$$
|
||||
v'(t) = -g/l \cdot \sin(u(t)), \quad u'(t) = v(t).
|
||||
$$
|
||||
|
||||
We can try the Euler method here. A simple approach might be this iteration scheme:
|
||||
|
||||
|
||||
$$
|
||||
\begin{align*}
|
||||
x_{n+1} &= x_n + h,\\
|
||||
u_{n+1} &= u_n + h v_n,\\
|
||||
v_{n+1} &= v_n - h \cdot g/l \cdot \sin(u_n).
|
||||
\end{align*}
|
||||
$$
|
||||
|
||||
Here we need *two* initial conditions: one for the initial value $u(t_0)$ and the initial value of $u'(t_0)$. We have seen if we start at an angle $a$ and release the bob from rest, so $u'(0)=0$ we get a sinusoidal answer to the linearized model. What happens here? We let $a=1$, $L=5$ and $g=9.8$:
|
||||
|
||||
|
||||
We write a function to solve this starting from $(x_0, y_0)$ and ending at $x_n$:
|
||||
|
||||
|
||||
```{julia}
|
||||
function euler2(x0, xn, y0, yp0, n; g=9.8, l = 5)
|
||||
xs, us, vs = zeros(n+1), zeros(n+1), zeros(n+1)
|
||||
xs[1], us[1], vs[1] = x0, y0, yp0
|
||||
h = (xn - x0)/n
|
||||
for i = 1:n
|
||||
xs[i+1] = xs[i] + h
|
||||
us[i+1] = us[i] + h * vs[i]
|
||||
vs[i+1] = vs[i] + h * (-g / l) * sin(us[i])
|
||||
end
|
||||
linterp(xs, us)
|
||||
end
|
||||
```
|
||||
|
||||
Let's take $a = \pi/4$ as the initial angle, then the approximate solution should be $\pi/4\cos(\sqrt{g/l}x)$ with period $T = 2\pi\sqrt{l/g}$. We try first to plot then over 4 periods:
|
||||
|
||||
|
||||
```{julia}
|
||||
𝗅, 𝗀 = 5, 9.8
|
||||
𝖳 = 2pi * sqrt(𝗅/𝗀)
|
||||
𝗑0, 𝗑n, 𝗒0, 𝗒p0 = 0, 4𝖳, pi/4, 0
|
||||
plot(euler2(𝗑0, 𝗑n, 𝗒0, 𝗒p0, 20), 0, 4𝖳)
|
||||
```
|
||||
|
||||
Something looks terribly amiss. The issue is the step size, $h$, is too large to capture the oscillations. There are basically only $5$ steps to capture a full up and down motion. Instead, we try to get $20$ steps per period so $n$ must be not $20$, but $4 \cdot 20 \cdot T \approx 360$. To this graph, we add the approximate one:
|
||||
|
||||
|
||||
```{julia}
|
||||
plot(euler2(𝗑0, 𝗑n, 𝗒0, 𝗒p0, 360), 0, 4𝖳)
|
||||
plot!(x -> pi/4*cos(sqrt(𝗀/𝗅)*x), 0, 4𝖳)
|
||||
```
|
||||
|
||||
Even now, we still see that something seems amiss, though the issue is not as dramatic as before. The oscillatory nature of the pendulum is seen, but in the Euler solution, the amplitude grows, which would necessarily mean energy is being put into the system. A familiar instance of a pendulum would be a child on a swing. Without pumping the legs - putting energy in the system - the height of the swing's arc will not grow. Though we now have oscillatory motion, this growth indicates the solution is still not quite right. The issue is likely due to each step mildly overcorrecting and resulting in an overall growth. One of the questions pursues this a bit further.
|
||||
|
||||
|
||||
## Questions
|
||||
|
||||
|
||||
##### Question
|
||||
|
||||
|
||||
Use Euler's method with $n=5$ to approximate $u(1)$ where
|
||||
|
||||
|
||||
$$
|
||||
u'(x) = x - u(x), \quad u(0) = 1
|
||||
$$
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
F(y,x) = x - y
|
||||
x0, xn, y0 = 0, 1, 1
|
||||
val = euler(F, x0, xn, y0, 5)(1)
|
||||
numericq(val)
|
||||
```
|
||||
|
||||
##### Question
|
||||
|
||||
|
||||
Consider the equation
|
||||
|
||||
|
||||
$$
|
||||
y' = x \cdot \sin(y), \quad y(0) = 1.
|
||||
$$
|
||||
|
||||
Use Euler's method with $n=50$ to find the value of $y(5)$.
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
F(y, x) = x * sin(y)
|
||||
x0, xn, y0 = 0, 5, 1
|
||||
n = 50
|
||||
u = euler(F, x0, xn, y0, n)
|
||||
numericq(u(xn))
|
||||
```
|
||||
|
||||
##### Question
|
||||
|
||||
|
||||
Consider the ordinary differential equation
|
||||
|
||||
|
||||
$$
|
||||
\frac{dy}{dx} = 1 - 2\frac{y}{x}, \quad y(1) = 0.
|
||||
$$
|
||||
|
||||
Use Euler's method to solve for $y(2)$ when $n=50$.
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
F(y, x) = 1 - 2y/x
|
||||
x0, xn, y0 = 1, 2, 0
|
||||
n = 50
|
||||
u = euler(F, x0, xn, y0, n)
|
||||
numericq(u(xn))
|
||||
```
|
||||
|
||||
##### Question
|
||||
|
||||
|
||||
Consider the ordinary differential equation
|
||||
|
||||
|
||||
$$
|
||||
\frac{dy}{dx} = \frac{y \cdot \log(y)}{x}, \quad y(2) = e.
|
||||
$$
|
||||
|
||||
Use Euler's method to solve for $y(3)$ when $n=25$.
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
F(y, x) = y*log(y)/x
|
||||
x0, xn, y0 = 2, 3, exp(1)
|
||||
n = 25
|
||||
u = euler(F, x0, xn, y0, n)
|
||||
numericq(u(xn))
|
||||
```
|
||||
|
||||
##### Question
|
||||
|
||||
|
||||
Consider the first-order non-linear ODE
|
||||
|
||||
|
||||
$$
|
||||
y' = y \cdot (1-2x), \quad y(0) = 1.
|
||||
$$
|
||||
|
||||
Use Euler's method with $n=50$ to approximate the solution $y$ over $[0,2]$.
|
||||
|
||||
|
||||
What is the value at $x=1/2$?
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
F(y, x) = y * (1-2x)
|
||||
x0, xn, y0 = 0, 2, 1
|
||||
n = 50
|
||||
u = euler(F, x0, xn, y0, n)
|
||||
numericq(u(1/2))
|
||||
```
|
||||
|
||||
What is the value at $x=3/2$?
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
F(y, x) = y * (1-2x)
|
||||
x0, xn, y0 = 0, 2, 1
|
||||
n = 50
|
||||
u = euler(F, x0, xn, y0, n)
|
||||
numericq(u(3/2))
|
||||
```
|
||||
|
||||
##### Question: The pendulum revisited.
|
||||
|
||||
|
||||
The issue with the pendulum's solution growing in amplitude can be addressed using a modification to the Euler method attributed to [Cromer](http://astro.physics.ncsu.edu/urca/course_files/Lesson14/index.html). The fix is to replace the term `sin(us[i])` in the line `vs[i+1] = vs[i] + h * (-g / l) * sin(us[i])` of the `euler2` function with `sin(us[i+1])`, which uses the updated angular velocity in the $2$nd step in place of the value before the step.
|
||||
|
||||
|
||||
Modify the `euler2` function to implement the Euler-Cromer method. What do you see?
|
||||
|
||||
|
||||
```{julia}
|
||||
#| hold: true
|
||||
#| echo: false
|
||||
choices = [
|
||||
"The same as before - the amplitude grows",
|
||||
"The solution is identical to that of the approximation found by linearization of the sine term",
|
||||
"The solution has a constant amplitude, but its period is slightly *shorter* than that of the approximate solution found by linearization",
|
||||
"The solution has a constant amplitude, but its period is slightly *longer* than that of the approximate solution found by linearization"]
|
||||
answ = 4
|
||||
radioq(choices, answ, keep_order=true)
|
||||
```
|
||||
|
||||
BIN
quarto/ODEs/figures/bead-game.jpg
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
quarto/ODEs/figures/euler.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
quarto/ODEs/figures/galileo.gif
Normal file
|
After Width: | Height: | Size: 885 B |
|
After Width: | Height: | Size: 98 KiB |
1011
quarto/ODEs/odes.qmd
Normal file
27
quarto/ODEs/process.jl
Normal file
@ -0,0 +1,27 @@
|
||||
using WeavePynb
|
||||
using Mustache
|
||||
|
||||
mmd(fname) = mmd_to_html(fname, BRAND_HREF="../toc.html", BRAND_NAME="Calculus with Julia")
|
||||
## uncomment to generate just .md files
|
||||
mmd(fname) = mmd_to_md(fname, BRAND_HREF="../toc.html", BRAND_NAME="Calculus with Julia")
|
||||
|
||||
fnames = [
|
||||
"odes",
|
||||
"euler"
|
||||
]
|
||||
|
||||
|
||||
|
||||
function process_file(nm, twice=false)
|
||||
include("$nm.jl")
|
||||
mmd_to_md("$nm.mmd")
|
||||
markdownToHTML("$nm.md")
|
||||
twice && markdownToHTML("$nm.md")
|
||||
end
|
||||
|
||||
process_files(twice=false) = [process_file(nm, twice) for nm in fnames]
|
||||
|
||||
"""
|
||||
## TODO ODEs
|
||||
|
||||
"""
|
||||
295
quarto/ODEs/solve.qmd
Normal file
@ -0,0 +1,295 @@
|
||||
# The problem-algorithm-solve interface
|
||||
|
||||
|
||||
```{julia}
|
||||
#| echo: false
|
||||
|
||||
import Logging
|
||||
Logging.disable_logging(Logging.Info) # or e.g. Logging.Info
|
||||
Logging.disable_logging(Logging.Warn)
|
||||
|
||||
import SymPy
|
||||
function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject}
|
||||
println(io, "<span class=\"math-left-align\" style=\"padding-left: 4px; width:0; float:left;\"> ")
|
||||
println(io, "\\[")
|
||||
println(io, sympy.latex(x))
|
||||
println(io, "\\]")
|
||||
println(io, "</span>")
|
||||
end
|
||||
|
||||
# hack to work around issue
|
||||
import Markdown
|
||||
import CalculusWithJulia
|
||||
function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...)
|
||||
nm = joinpath("..", string(d), f)
|
||||
u = ""
|
||||
Markdown.parse(u)
|
||||
end
|
||||
|
||||
nothing
|
||||
```
|
||||
|
||||
This section uses these add-on packages:
|
||||
|
||||
|
||||
```{julia}
|
||||
using Plots
|
||||
using MonteCarloMeasurements
|
||||
```
|
||||
|
||||
```{julia}
|
||||
#| echo: false
|
||||
#| results: "hidden"
|
||||
using CalculusWithJulia.WeaveSupport
|
||||
|
||||
const frontmatter = (
|
||||
title = "The problem-algorithm-solve interface",
|
||||
description = "Calculus with Julia: The problem-algorithm-solve interface",
|
||||
tags = ["CalculusWithJulia", "odes", "the problem-algorithm-solve interface"],
|
||||
);
|
||||
fig_size = (800, 600)
|
||||
nothing
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
The [DifferentialEquations.jl](https://github.com/SciML) package is an entry point to a suite of `Julia` packages for numerically solving differential equations in `Julia` and other languages. A common interface is implemented that flexibly adjusts to the many different problems and algorithms covered by this suite of packages. In this section, we review a very informative [post](https://discourse.julialang.org/t/function-depending-on-the-global-variable-inside-module/64322/10) by discourse user `@genkuroki` which very nicely demonstrates the usefulness of the problem-algorithm-solve approach used with `DifferentialEquations.jl`. We slightly modify the presentation below for our needs, but suggest a perusal of the original post.
|
||||
|
||||
|
||||
##### Example: FreeFall
|
||||
|
||||
|
||||
The motion of an object under a uniform gravitational field is of interest.
|
||||
|
||||
|
||||
The parameters that govern the equation of motions are the gravitational constant, `g`; the initial height, `y0`; and the initial velocity, `v0`. The time span for which a solution is sought is `tspan`.
|
||||
|
||||
|
||||
A problem consists of these parameters. Typical `Julia` usage would be to create a structure to hold the parameters, which may be done as follows:
|
||||
|
||||
|
||||
```{julia}
|
||||
struct Problem{G, Y0, V0, TS}
|
||||
g::G
|
||||
y0::Y0
|
||||
v0::V0
|
||||
tspan::TS
|
||||
end
|
||||
|
||||
Problem(;g=9.80665, y0=0.0, v0=30.0, tspan=(0.0,8.0)) = Problem(g, y0, v0, tspan)
|
||||
```
|
||||
|
||||
The above creates a type, `Problem`, *and* a default constructor with default values. (The original uses a more sophisticated setup that allows the two things above to be combined.)
|
||||
|
||||
|
||||
Just calling `Problem()` will create a problem suitable for the earth, passing different values for `g` would be possible for other planets.
|
||||
|
||||
|
||||
To solve differential equations there are many different possible algorithms. Here is the construction of two types to indicate two algorithms:
|
||||
|
||||
|
||||
```{julia}
|
||||
struct EulerMethod{T}
|
||||
dt::T
|
||||
end
|
||||
EulerMethod(; dt=0.1) = EulerMethod(dt)
|
||||
|
||||
struct ExactFormula{T}
|
||||
dt::T
|
||||
end
|
||||
ExactFormula(; dt=0.1) = ExactFormula(dt)
|
||||
```
|
||||
|
||||
The above just specifies a type for dispatch –- the directions indicating what code to use to solve the problem. As seen, each specifies a size for a time step with default of `0.1`.
|
||||
|
||||
|
||||
A type for solutions is useful for different `show` methods or other methods. One can be created through:
|
||||
|
||||
|
||||
```{julia}
|
||||
struct Solution{Y, V, T, P<:Problem, A}
|
||||
y::Y
|
||||
v::V
|
||||
t::T
|
||||
prob::P
|
||||
alg::A
|
||||
end
|
||||
```
|
||||
|
||||
The different algorithms then can be implemented as part of a generic `solve` function. Following the post we have:
|
||||
|
||||
|
||||
```{julia}
|
||||
solve(prob::Problem) = solve(prob, default_algorithm(prob))
|
||||
default_algorithm(prob::Problem) = EulerMethod()
|
||||
|
||||
function solve(prob::Problem, alg::ExactFormula)
|
||||
g, y0, v0, tspan = prob.g, prob.y0, prob.v0, prob.tspan
|
||||
dt = alg.dt
|
||||
t0, t1 = tspan
|
||||
t = range(t0, t1 + dt/2; step = dt)
|
||||
|
||||
y(t) = y0 + v0*(t - t0) - g*(t - t0)^2/2
|
||||
v(t) = v0 - g*(t - t0)
|
||||
|
||||
Solution(y.(t), v.(t), t, prob, alg)
|
||||
end
|
||||
|
||||
function solve(prob::Problem, alg::EulerMethod)
|
||||
g, y0, v0, tspan = prob.g, prob.y0, prob.v0, prob.tspan
|
||||
dt = alg.dt
|
||||
t0, t1 = tspan
|
||||
t = range(t0, t1 + dt/2; step = dt)
|
||||
|
||||
n = length(t)
|
||||
y = Vector{typeof(y0)}(undef, n)
|
||||
v = Vector{typeof(v0)}(undef, n)
|
||||
y[1] = y0
|
||||
v[1] = v0
|
||||
|
||||
for i in 1:n-1
|
||||
v[i+1] = v[i] - g*dt # F*h step of Euler
|
||||
y[i+1] = y[i] + v[i]*dt # F*h step of Euler
|
||||
end
|
||||
|
||||
Solution(y, v, t, prob, alg)
|
||||
end
|
||||
```
|
||||
|
||||
The post has a more elegant means to unpack the parameters from the structures, but for each of the above, the parameters are unpacked, and then the corresponding algorithm employed. As of version `v1.7` of `Julia`, the syntax `(;g,y0,v0,tspan) = prob` could also be employed.
|
||||
|
||||
|
||||
The exact formulas, `y(t) = y0 + v0*(t - t0) - g*(t - t0)^2/2` and `v(t) = v0 - g*(t - t0)`, follow from well-known physics formulas. Each answer is wrapped in a `Solution` type so that the answers found can be easily extracted in a uniform manner.
|
||||
|
||||
|
||||
For example, plots of each can be obtained through:
|
||||
|
||||
|
||||
```{julia}
|
||||
earth = Problem()
|
||||
sol_euler = solve(earth)
|
||||
sol_exact = solve(earth, ExactFormula())
|
||||
|
||||
plot(sol_euler.t, sol_euler.y;
|
||||
label="Euler's method (dt = $(sol_euler.alg.dt))", ls=:auto)
|
||||
plot!(sol_exact.t, sol_exact.y; label="exact solution", ls=:auto)
|
||||
title!("On the Earth"; xlabel="t", legend=:bottomleft)
|
||||
```
|
||||
|
||||
Following the post, since the time step `dt = 0.1` is not small enough, the error of the Euler method is rather large. Next we change the algorithm parameter, `dt`, to be smaller:
|
||||
|
||||
|
||||
```{julia}
|
||||
earth₂ = Problem()
|
||||
sol_euler₂ = solve(earth₂, EulerMethod(dt = 0.01))
|
||||
sol_exact₂ = solve(earth₂, ExactFormula())
|
||||
|
||||
plot(sol_euler₂.t, sol_euler₂.y;
|
||||
label="Euler's method (dt = $(sol_euler₂.alg.dt))", ls=:auto)
|
||||
plot!(sol_exact₂.t, sol_exact₂.y; label="exact solution", ls=:auto)
|
||||
title!("On the Earth"; xlabel="t", legend=:bottomleft)
|
||||
```
|
||||
|
||||
It is worth noting that only the first line is modified, and only the method requires modification.
|
||||
|
||||
|
||||
Were the moon to be considered, the gravitational constant would need adjustment. This parameter is part of the problem, not the solution algorithm.
|
||||
|
||||
|
||||
Such adjustments are made by passing different values to the `Problem` constructor:
|
||||
|
||||
|
||||
```{julia}
|
||||
moon = Problem(g = 1.62, tspan = (0.0, 40.0))
|
||||
sol_eulerₘ = solve(moon)
|
||||
sol_exactₘ = solve(moon, ExactFormula(dt = sol_euler.alg.dt))
|
||||
|
||||
plot(sol_eulerₘ.t, sol_eulerₘ.y;
|
||||
label="Euler's method (dt = $(sol_eulerₘ.alg.dt))", ls=:auto)
|
||||
plot!(sol_exactₘ.t, sol_exactₘ.y; label="exact solution", ls=:auto)
|
||||
title!("On the Moon"; xlabel="t", legend=:bottomleft)
|
||||
```
|
||||
|
||||
The code above also adjusts the time span in addition to the graviational constant. The algorithm for exact formula is set to use the `dt` value used in the `euler` formula, for easier comparison. Otherwise, outside of the labels, the patterns are the same. Only those things that need changing are changed, the rest comes from defaults.
|
||||
|
||||
|
||||
The above shows the benefits of using a common interface. Next, the post illustrates how *other* authors could extend this code, simply by adding a *new* `solve` method. For example,
|
||||
|
||||
|
||||
```{julia}
|
||||
struct Symplectic2ndOrder{T}
|
||||
dt::T
|
||||
end
|
||||
Symplectic2ndOrder(;dt=0.1) = Symplectic2ndOrder(dt)
|
||||
|
||||
function solve(prob::Problem, alg::Symplectic2ndOrder)
|
||||
g, y0, v0, tspan = prob.g, prob.y0, prob.v0, prob.tspan
|
||||
dt = alg.dt
|
||||
t0, t1 = tspan
|
||||
t = range(t0, t1 + dt/2; step = dt)
|
||||
|
||||
n = length(t)
|
||||
y = Vector{typeof(y0)}(undef, n)
|
||||
v = Vector{typeof(v0)}(undef, n)
|
||||
y[1] = y0
|
||||
v[1] = v0
|
||||
|
||||
for i in 1:n-1
|
||||
ytmp = y[i] + v[i]*dt/2
|
||||
v[i+1] = v[i] - g*dt
|
||||
y[i+1] = ytmp + v[i+1]*dt/2
|
||||
end
|
||||
|
||||
Solution(y, v, t, prob, alg)
|
||||
end
|
||||
```
|
||||
|
||||
Had the two prior methods been in a package, the other user could still extend the interface, as above, with just a slight standard modification.
|
||||
|
||||
|
||||
The same approach works for this new type:
|
||||
|
||||
|
||||
```{julia}
|
||||
|
||||
earth₃ = Problem()
|
||||
sol_sympl₃ = solve(earth₃, Symplectic2ndOrder(dt = 2.0))
|
||||
sol_exact₃ = solve(earth₃, ExactFormula())
|
||||
|
||||
plot(sol_sympl₃.t, sol_sympl₃.y; label="2nd order symplectic (dt = $(sol_sympl₃.alg.dt))", ls=:auto)
|
||||
plot!(sol_exact₃.t, sol_exact₃.y; label="exact solution", ls=:auto)
|
||||
title!("On the Earth"; xlabel="t", legend=:bottomleft)
|
||||
```
|
||||
|
||||
Finally, the author of the post shows how the interface can compose with other packages in the `Julia` package ecosystem. This example uses the external package `MonteCarloMeasurements` which plots the behavior of the system for perturbations of the initial value:
|
||||
|
||||
|
||||
```{julia}
|
||||
|
||||
earth₄ = Problem(y0 = 0.0 ± 0.0, v0 = 30.0 ± 1.0)
|
||||
sol_euler₄ = solve(earth₄)
|
||||
sol_sympl₄ = solve(earth₄, Symplectic2ndOrder(dt = 2.0))
|
||||
sol_exact₄ = solve(earth₄, ExactFormula())
|
||||
|
||||
ylim = (-100, 60)
|
||||
P = plot(sol_euler₄.t, sol_euler₄.y;
|
||||
label="Euler's method (dt = $(sol_euler₄.alg.dt))", ls=:auto)
|
||||
title!("On the Earth"; xlabel="t", legend=:bottomleft, ylim)
|
||||
|
||||
Q = plot(sol_sympl₄.t, sol_sympl₄.y;
|
||||
label="2nd order symplectic (dt = $(sol_sympl₄.alg.dt))", ls=:auto)
|
||||
title!("On the Earth"; xlabel="t", legend=:bottomleft, ylim)
|
||||
|
||||
R = plot(sol_exact₄.t, sol_exact₄.y; label="exact solution", ls=:auto)
|
||||
title!("On the Earth"; xlabel="t", legend=:bottomleft, ylim)
|
||||
|
||||
plot(P, Q, R; size=(720, 600))
|
||||
```
|
||||
|
||||
The only change was in the problem, `Problem(y0 = 0.0 ± 0.0, v0 = 30.0 ± 1.0)`, where a different number type is used which accounts for uncertainty. The rest follows the same pattern.
|
||||
|
||||
|
||||
This example, shows the flexibility of the problem-algorithm-solver pattern while maintaining a consistent pattern for execution.
|
||||
|
||||
|
||||
11
quarto/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# CalculusWithJulia via quarto
|
||||
|
||||
To compile the pages through quarto
|
||||
|
||||
|
||||
* author in `.jmd` files (to be run through pluto)
|
||||
* run `julia make_qmd.jl` to convert to `.qmd` files
|
||||
* compile with `quarto`
|
||||
|
||||
The files in subdirectories are generated, they should not be edited
|
||||
The files in this main directory are quarto specific.
|
||||
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 76 KiB |
15
quarto/_freeze/ODEs/euler/execute-results/html.json
Normal file
106
quarto/_freeze/ODEs/euler/figure-html/cell-10-output-1.svg
Normal file
|
After Width: | Height: | Size: 20 KiB |
110
quarto/_freeze/ODEs/euler/figure-html/cell-13-output-1.svg
Normal file
|
After Width: | Height: | Size: 20 KiB |
110
quarto/_freeze/ODEs/euler/figure-html/cell-16-output-1.svg
Normal file
|
After Width: | Height: | Size: 22 KiB |
689
quarto/_freeze/ODEs/euler/figure-html/cell-19-output-1.svg
Normal file
|
After Width: | Height: | Size: 56 KiB |
107
quarto/_freeze/ODEs/euler/figure-html/cell-24-output-1.svg
Normal file
|
After Width: | Height: | Size: 24 KiB |
698
quarto/_freeze/ODEs/euler/figure-html/cell-25-output-1.svg
Normal file
|
After Width: | Height: | Size: 64 KiB |
122
quarto/_freeze/ODEs/euler/figure-html/cell-26-output-1.svg
Normal file
|
After Width: | Height: | Size: 27 KiB |