Skip to content

Commit 0835dba

Browse files
committed
Add lecture 12
1 parent d877356 commit 0835dba

File tree

19 files changed

+6312
-5
lines changed

19 files changed

+6312
-5
lines changed

docs_vitepress/make.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ pages = [
8484
# "Lecture" => "lecture.md",
8585
# "Lab" => "lab.md",
8686
# ]),
87-
# "12: Ordinary Differential Equations" => add_prefix("lecture_12", [
88-
# "Lecture" => "lecture.md",
89-
# "Lab" => "lab.md",
90-
# "Homework" => "hw.md",
91-
# ]),
87+
"12: Ordinary Differential Equations" => add_prefix("lecture_12", [
88+
"Lecture" => "lecture.md",
89+
"Lab" => "lab.md",
90+
"Homework" => "hw.md",
91+
]),
9292
]),
9393
]
9494

docs_vitepress/src/lectures/lecture_12/LV_GaussNum.svg

Lines changed: 466 additions & 0 deletions
Loading

docs_vitepress/src/lectures/lecture_12/LV_GaussNum2.svg

Lines changed: 454 additions & 0 deletions
Loading

docs_vitepress/src/lectures/lecture_12/LV_Measurements.svg

Lines changed: 454 additions & 0 deletions
Loading

docs_vitepress/src/lectures/lecture_12/LV_Measurements2.svg

Lines changed: 454 additions & 0 deletions
Loading

docs_vitepress/src/lectures/lecture_12/LV_Quadrics.svg

Lines changed: 460 additions & 0 deletions
Loading

docs_vitepress/src/lectures/lecture_12/LV_ensemble.svg

Lines changed: 2368 additions & 0 deletions
Loading
685 KB
Loading
45 KB
Loading
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# [Homework 12 - The Runge-Kutta ODE Solver](@id hw12)
2+
3+
There exist many different ODE solvers. To demonstrate how we can get
4+
significantly better results with a simple update to `Euler`, you will
5+
implement the second order Runge-Kutta method `RK2`:
6+
7+
```math
8+
\begin{align*}
9+
\tilde x_{n+1} &= x_n + hf(x_n, t_n)\\
10+
x_{n+1} &= x_n + \frac{h}{2}(f(x_n,t_n)+f(\tilde x_{n+1},t_{n+1}))
11+
\end{align*}
12+
```
13+
14+
`RK2` is a 2nd order method. It uses not only $f$ (the slope at a given point),
15+
but also $f'$ (the derivative of the slope). With some clever manipulations you
16+
can arrive at the equations above with make use of $f'$ without needing an
17+
explicit expression for it (if you want to know how, see
18+
[here](https://web.mit.edu/10.001/Web/Course_Notes/Differential_Equations_Notes/node5.html)).
19+
Essentially, `RK2` computes an initial guess $\tilde x_{n+1}$ to then average
20+
the slopes at the current point $x_n$ and at the guess $\tilde x_{n+1}$ which
21+
is illustarted below.
22+
![rk2](rk2.png)
23+
24+
The code from the lab that you will need for this homework is given below.
25+
As always, put all your code in a file called `hw.jl`, zip it, and upload it
26+
to BRUTE.
27+
28+
```@example hw
29+
struct ODEProblem{F,T<:Tuple{Number,Number},U<:AbstractVector,P<:AbstractVector}
30+
f::F
31+
tspan::T
32+
u0::U
33+
θ::P
34+
end
35+
36+
abstract type ODESolver end
37+
38+
struct Euler{T} <: ODESolver
39+
dt::T
40+
end
41+
42+
function (solver::Euler)(prob::ODEProblem, u, t)
43+
f, θ, dt = prob.f, prob.θ, solver.dt
44+
(u + dt*f(u,θ), t+dt)
45+
end
46+
47+
function solve(prob::ODEProblem, solver::ODESolver)
48+
t = prob.tspan[1]; u = prob.u0
49+
us = [u]; ts = [t]
50+
while t < prob.tspan[2]
51+
(u,t) = solver(prob, u, t)
52+
push!(us,u)
53+
push!(ts,t)
54+
end
55+
ts, reduce(hcat,us)
56+
end
57+
58+
# Define & Solve ODE
59+
60+
function lotkavolterra(x,θ)
61+
α, β, γ, δ = θ
62+
x₁, x₂ = x
63+
64+
dx₁ = α*x₁ - β*x₁*x₂
65+
dx₂ = δ*x₁*x₂ - γ*x₂
66+
67+
[dx₁, dx₂]
68+
end
69+
nothing # hide
70+
```
71+
72+
::: danger Homework (2 points)
73+
74+
Implement the 2nd order Runge-Kutta solver according to the equations given above
75+
by overloading the call method of a new type `RK2`.
76+
77+
```julia
78+
(solver::RK2)(prob::ODEProblem, u, t)
79+
```
80+
81+
:::
82+
83+
```@setup hw
84+
struct RK2{T} <: ODESolver
85+
dt::T
86+
end
87+
88+
function (solver::RK2)(prob::ODEProblem, u, t)
89+
f, θ, dt = prob.f, prob.θ, solver.dt
90+
du = f(u,θ)
91+
uh = u + du*dt
92+
u + dt/2*(du + f(uh,θ)), t+dt
93+
end
94+
```
95+
96+
You should be able to use it exactly like our `Euler` solver before:
97+
98+
```@example hw
99+
using Plots
100+
using JLD2
101+
102+
# Define ODE
103+
function lotkavolterra(x,θ)
104+
α, β, γ, δ = θ
105+
x₁, x₂ = x
106+
107+
dx₁ = α*x₁ - β*x₁*x₂
108+
dx₂ = δ*x₁*x₂ - γ*x₂
109+
110+
[dx₁, dx₂]
111+
end
112+
113+
θ = [0.1,0.2,0.3,0.2]
114+
u0 = [1.0,1.0]
115+
tspan = (0.,100.)
116+
prob = ODEProblem(lotkavolterra,tspan,u0,θ)
117+
118+
# load correct data
119+
true_data = load("lotkadata.jld2")
120+
121+
# create plot
122+
p1 = plot(true_data["t"], true_data["u"][1,:], lw=4, ls=:dash, alpha=0.7,
123+
color=:gray, label="x Truth")
124+
plot!(p1, true_data["t"], true_data["u"][2,:], lw=4, ls=:dash, alpha=0.7,
125+
color=:gray, label="y Truth")
126+
127+
# Euler solve
128+
(t,X) = solve(prob, Euler(0.2))
129+
plot!(p1,t,X[1,:], color=3, lw=3, alpha=0.8, label="x Euler", ls=:dot)
130+
plot!(p1,t,X[2,:], color=4, lw=3, alpha=0.8, label="y Euler", ls=:dot)
131+
132+
# RK2 solve
133+
(t,X) = solve(prob, RK2(0.2))
134+
plot!(p1,t,X[1,:], color=1, lw=3, alpha=0.8, label="x RK2")
135+
plot!(p1,t,X[2,:], color=2, lw=3, alpha=0.8, label="y RK2")
136+
```

0 commit comments

Comments
 (0)