IVP: focus on single point methods (advance using only the previous point), as opposed to multi-step methods.
This equation has the exact solution $$y(t) = y_0e^{-at}.$$
import Plots as plt
function ode_EE(f, y0, t)
ns = length(t)-1
y = zeros(ns+1)
y[1] = y0
for k in 1:ns
Δt = t[k+1] - t[k]
y[k+1] = y[k] + Δt*f(y[k],t[k])
end
return y
end
#---------------
myfunc(y,t) = -1.1*y
#---------------
y0 = 1
tend = 6.0
t = LinRange(0, tend, 20)
y = ode_EE(myfunc, y0, t)
plt.resetfontsizes(); plt.scalefontsizes(1.3)
plt.scatter(t,y, label="EE")
plt.plot!(t->y0*exp(-1.1*t), lw=2, label="Exact")
plt.plot!(xlabel="t", ylabel="y", foreground_color_legend=nothing, background_color=nothing)
y0 = 1
a = 1.1
tend = 6.0
t = LinRange(0.0, tend, 20)
ns = length(t) - 1
y = zeros(ns+1)
y[1] = y0
for k in 1:ns # have n points, take n-1 steps
Δt = t[k+1]-t[k]
y[k+1] = y[k]/(1+a*Δt)
end
plt.resetfontsizes(); plt.scalefontsizes(1.3)
plt.scatter(t,y, label="IE")
plt.plot!(t->y0*exp(-a*t), lw=2, label="Exact")
plt.plot!(xlabel="t", ylabel="y")
plt.plot!(foreground_color_legend=nothing, background_color_legend=nothing)
using NLsolve
function ode_IE(f, y0, t)
ns = length(t) - 1
y = zeros(ns+1)
y[1] = y0
function F!(Fval, ynext)
Fval[1] = ynext[1]-y[kk]-Δt*f(ynext[1],t[kk+1])
end
kk = undef # get index into the function scope for use in F!
for k in 1:ns
kk = k
Δt = t[k+1]-t[k]
tkp1 = t[k+1]
results = nlsolve(F!, [y[k]])
y[k+1] = results.zero[1]
end
return y
end
#------------------
myfunc(y,t) = -y^0.8
#------------------
y0 = 1.0
tend = 3.0
t = LinRange(0.0, tend, 20)
n = length(t)
yEE = ode_EE(myfunc,y0,t)
yIE = ode_IE(myfunc,y0,t)
#---------------------
plt.resetfontsizes(); plt.scalefontsizes(1.3)
plt.plot(t,yEE,lw=2, label="EE")
plt.plot!(t->(1-0.2*t)^(1/0.2), label="Exact", ls=:dash, color="black" )
plt.plot!(t,yIE,lw=2, label="IE")
plt.plot!(foreground_color_legend=nothing, background_color_legend=nothing)
plt.plot!(xlabel="t", ylabel="y")