WIP
This commit is contained in:
@@ -79,7 +79,7 @@ R(0) &= 0\\
|
||||
\end{align*}
|
||||
$$
|
||||
|
||||
In `Julia` we define these, `N` to model the total population, and `u0` to be the proportions.
|
||||
In `Julia` we define these parameter values and `N` to model the total population and `u0` to be represent the proportions.
|
||||
|
||||
|
||||
```{julia}
|
||||
@@ -94,7 +94,7 @@ An *estimated* set of values for $k$ and $b$ are $k=1/3$, coming from the averag
|
||||
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:
|
||||
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.) This is a single ODE. The solution would be achieved through:
|
||||
|
||||
|
||||
```{julia}
|
||||
@@ -102,10 +102,12 @@ To warm up, if $b=0$ then $i'(t) = -k \cdot i(t)$ describes the infected. (The
|
||||
k = 1/3
|
||||
|
||||
f(u,p,t) = -k * u # solving u′(t) = - k u(t)
|
||||
|
||||
uᵢ0= I0/N
|
||||
time_span = (0.0, 20.0)
|
||||
|
||||
prob = ODEProblem(f, I0/N, time_span)
|
||||
sol = solve(prob, Tsit5(), reltol=1e-8, abstol=1e-8)
|
||||
prob = ODEProblem(f, uᵢ0, time_span)
|
||||
sol = solve(prob, Tsit5(); reltol=1e-8, abstol=1e-8)
|
||||
|
||||
plot(sol)
|
||||
```
|
||||
@@ -120,7 +122,7 @@ $$
|
||||
\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$.
|
||||
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 was labeled with an $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.
|
||||
@@ -167,7 +169,7 @@ The `sir!` function has the trailing `!` indicating – by convention – it *mu
|
||||
|
||||
:::
|
||||
|
||||
With the update function defined, the problem is setup and a solution found with in the same manner:
|
||||
With the update function defined, the problem is setup and a solution is found using the same manner as before:
|
||||
|
||||
|
||||
```{julia}
|
||||
@@ -193,7 +195,7 @@ 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)
|
||||
plot(sol; legend=:right)
|
||||
```
|
||||
|
||||
The graphs are somewhat similar, but the steady state is reached much more quickly and nearly everyone became infected.
|
||||
@@ -252,7 +254,7 @@ 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$.
|
||||
(A 3-dimensional graph with `plotly` or `Makie` 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.
|
||||
@@ -382,7 +384,7 @@ 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:
|
||||
Finally, we note that the `ModelingToolkit` package provides symbolic-numeric computing. This allows the equations to be set up symbolically, as has been illustrated with `SymPy`, before being passed off to `DifferentialEquations` to solve numerically. The above example with no wind resistance could be translated into the following:
|
||||
|
||||
|
||||
```{julia}
|
||||
|
||||
@@ -118,10 +118,10 @@ function solve(prob::Problem, alg::EulerMethod)
|
||||
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 post has a more elegant means to unpack the parameters from the structures, but for each of the above, the parameters are unpacked using the dot notation for `getproperty`, and then the corresponding algorithm employed. As of version `v1.7` of `Julia`, the syntax `(;g,y0,v0,tspan) = prob` could also have been 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.
|
||||
The exact answers, `y(t) = y0 + v0*(t - t0) - g*(t - t0)^2/2` and `v(t) = v0 - g*(t - t0)`, follow from well-known physics formulas for constant-acceleration motion. 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:
|
||||
@@ -138,7 +138,9 @@ 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:
|
||||
Following the post, since the time step `dt = 0.1` is not small enough, the error of the Euler method is readily identified.
|
||||
|
||||
Next we change the algorithm parameter, `dt`, to be smaller:
|
||||
|
||||
|
||||
```{julia}
|
||||
@@ -155,7 +157,7 @@ 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.
|
||||
Were the moon to be considered, the gravitational constant would need adjustment. This parameter is a property of the problem, not the solution algorithm, as `dt` is.
|
||||
|
||||
|
||||
Such adjustments are made by passing different values to the `Problem` constructor:
|
||||
@@ -175,7 +177,9 @@ 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,
|
||||
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, a sympletic method conserves a quantity, so can track long-term evolution without drift.
|
||||
|
||||
|
||||
```{julia}
|
||||
|
||||
Reference in New Issue
Block a user