MMSB: Mathematical Modeling in Systems Biology / Apr 10 2020
HW2 solution
Python
import numpy as npimport matplotlib.pyplot as plt%matplotlib inline2.8s
Python
def lv(u, p, t): x, y = u a, b, c, d = p dx = a * x - b * x * y dy = -c * y + d * x * y return np.array([dx, dy])0.0s
Python
# ODE solverdef solve_euler(f, u0, tspan, h, p): ts = np.arange(tspan[0], tspan[1] + h, h) us = np.zeros((len(ts), len(u0))) us[0, :] = np.asarray(u0) for i in range(1, len(ts)): u = us[i-1,:] t = ts[i-1] nextu = u + h * f(u, p, t) us[i,:] = nextu return {"t": ts, "y": np.asarray(us)}0.0s
Python
h = 0.001u0 = [2.0, 1.0]ts = (0.0, 30.0)p = (2/3, 4/3, 1, 1)sol = solve_euler(lv, u0, ts, h, p)plt.figure(figsize=(10, 7))plt.plot(sol["t"], sol["y"][:, 0], label="x")plt.plot(sol["t"], sol["y"][:, 1], label="y")plt.legend(loc="best")0.8s
Python
<matplotlib.legend.Legend at 0x7f5e364b2f90>
# Comparison between time steps (h) u0 = [2.0, 1.0]ts = (0.0, 30.0)p = (2/3, 4/3, 1, 1)sols = [solve_euler(lv, u0, ts, h, p) for h in (0.001, 0.005, 0.01, 0.05, 0.1)]plt.figure(figsize=(15, 10))for sol in sols: plt.plot(sol["t"], sol["y"][:, 0], label="x") plt.plot(sol["t"], sol["y"][:, 1], label="y")0.8s
Python
def solve_rk4(f, u0, tspan, h, p): ts = np.arange(tspan[0], tspan[1] + h, h) us = np.zeros((len(ts), len(u0))) us[0, :] = np.asarray(u0) for i in range(1, len(ts)): u = us[i-1,:] t = ts[i-1] k1 = h * f(u, p, t) k2 = h * f(u + 0.5 * k1, p, t + 0.5 * h) k3 = h * f(u + 0.5 * k2, p, t + 0.5 * h) k4 = h * f(u + k3, p, t + h) nextu = u + (k1 + 2*k2 + 2*k3+ k4) / 6 us[i,:] = nextu return {"t": ts, "y": np.asarray(us)}0.1s
Python
# Comparison between FE and RK4 (h(RK4) = 0.01, h(FE) = 0.001)u0 = [2.0, 1.0]ts = (0.0, 30.0)p = (2/3, 4/3, 1, 1)solrk = solve_rk4(lv, u0, ts, 0.01, p)solfe = solve_euler(lv, u0, ts, 0.001, p)plt.figure(figsize=(10, 7))plt.plot(solrk["t"], solrk["y"][:, 0], label="x (RK)")plt.plot(solrk["t"], solrk["y"][:, 1], label="y (RK)")plt.plot(solfe["t"], solfe["y"][:, 0], '--', label="x (FE)")plt.plot(solfe["t"], solfe["y"][:, 1], '--', label="y (FE)")plt.legend(loc="best")0.7s
Python
<matplotlib.legend.Legend at 0x7f5e3635cd90>
# Comparison between FE and RK4 (h = 0.01)u0 = [2.0, 1.0]ts = (0.0, 30.0)p = (2/3, 4/3, 1, 1)solrk = solve_rk4(lv, u0, ts, 0.01, p)solfe = solve_euler(lv, u0, ts, 0.01, p)plt.figure(figsize=(10, 7))plt.plot(solrk["t"], solrk["y"][:, 0], label="x (RK)")plt.plot(solrk["t"], solrk["y"][:, 1], label="y (RK)")plt.plot(solfe["t"], solfe["y"][:, 0], '--', label="x (FE)")plt.plot(solfe["t"], solfe["y"][:, 1], '--', label="y (FE)")plt.legend(loc="best")0.7s
Python
<matplotlib.legend.Legend at 0x7f5e361f4990>
# I use solve_ivp() instead of odeint() so that the solver could determine the time step itselffrom scipy.integrate import solve_ivpsol = solve_ivp(lambda t, y: lv(y, p, t), ts, u0, dense_output=True, method="RK45")sol0.3s
Python
# To get smooth curves, use interpolantst = np.linspace(ts[0], ts[1], num=500)y = sol.sol(t).transpose()plt.figure(figsize=(15, 10))plt.plot(t, y)plt.plot(solrk["t"], solrk["y"], '--')plt.plot(solfe["t"], solfe["y"])1.0s
Python
[<matplotlib.lines.Line2D at 0x7f5e2e4bc110>,
<matplotlib.lines.Line2D at 0x7f5e2e4bcd90>]
Julia
using Pkgpkg"up; add DifferentialEquations Plots"122.4s
Julia
function lv(u, p, t) x, y = u a, b, c, d = p dx = a * x - b * x * y dy = -c * y + d * x * y return [dx, dy]end0.5s
Julia
lv (generic function with 1 method)
# ODE solverfunction solve_euler(f, u0, tspan, h, p) ts = tspan[1]:h:tspan[end] us = zeros(length(ts), length(u0)) us[1, :] .= u0 for i in 2:length(ts) us[i, :] .= us[i-1, :] .+ h .* f(us[i-1, :], p, ts[i-1]) end return (t = ts, u = us)end0.6s
Julia
solve_euler (generic function with 1 method)
h = 0.001u0 = [2.0, 1.0]ts = (0.0, 30.0)p = (2/3, 4/3, 1, 1)ts, us = solve_euler(lv, u0, ts, h, p)1.2s
Julia
(t = 0.0:0.001:30.0, u = [2.0 1.0; 1.99867 1.001; … ; 0.474506 0.16177; 0.47472 0.161685])
using Plotsplot(ts, us)109.7s
Julia
function solve_rk4(f, u0, tspan, h, p) ts = tspan[1]:h:tspan[end] us = zeros(length(ts), length(u0)) us[1, :] .= u0 for i in 2:length(ts) u = us[i-1, :] t = ts[i-1] k1 = h * f(u, p, t) k2 = h * f(u + 0.5 * k1, p, t + 0.5 * h) k3 = h * f(u + 0.5 * k2, p, t + 0.5 * h) k4 = h * f(u + k3, p, t + h) us[i,:] = u + (k1 + 2* k2 + 2*k3 + k4) / 6 end return (t = ts, u = us)end0.6s
Julia
solve_rk4 (generic function with 1 method)
solrk = solve_rk4(lv, u0, ts, 0.01, p)0.3s
Julia
(t = 0.0:0.01:30.0, u = [2.0 1.0; 1.98658 1.00998; … ; 0.482421 0.16222; 0.484601 0.161385])
plot(solrk.t, solrk.u)0.7s
Julia
solfe = solve_euler(lv, u0, ts, 0.01, p)0.5s
Julia
(t = 0.0:0.01:30.0, u = [2.0 1.0; 1.98667 1.01; … ; 0.386418 0.168918; 0.388124 0.167882])
plot(solrk.t, solrk.u, labels=["x (RK4)" "y (RK4)"])plot!(solfe.t, solfe.u, labels=["x (Euler)" "y (Euler)"], legend=:topleft)0.7s
Julia