Code
%reset -f
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fsolve
# variables globales
t0 = 0
tfinal = 5
y0 = 4
##############################################
# solution exacte
##############################################
import sympy
sympy.init_printing()
phi_sym = lambda t,y: (4*sympy.cos(2*sympy.pi*t)-4*t**2)*y
t = sympy.Symbol('t')
y = sympy.Function('y')
edo = sympy.Eq( sympy.diff(y(t),t) , phi_sym(t,y(t)) )
solgen = sympy.dsolve(edo,y(t))
display(solgen)
consts = sympy.solve( sympy.Eq( y0, solgen.rhs.subs(t,t0)) , dict=True)[0]
display(consts)
solpar = solgen.subs(consts).simplify()
display(solpar)
##############################################
# solution approchée
##############################################
sol_exacte = sympy.lambdify(t,solpar.rhs,'numpy')
phi = lambda t,y: (4*np.cos(2*np.pi*t)-4*t**2)*y
def RK(tt,phi,y0,sigma,gamma,eta):
h = tt[1]-tt[0]
uu = np.zeros_like(tt)
uu[0] = y0
for i in range(len(tt)-1):
K1 = phi( tt[i] , uu[i] )
K2 = phi( tt[i]+h*eta , uu[i]+h*eta*K1 )
K3 = phi( tt[i]+h*sigma , uu[i]+h*sigma*K2 )
uu[i+1] = uu[i]+h*((1-gamma)*K1+gamma*K3)
return uu
##############################################
# ordre
##############################################
H = []
err_1, err_2, err_3 = [], [], []
plt.figure(figsize=(16,10))
ax11 = plt.subplot(3,2,1)
ax12 = plt.subplot(3,2,2)
ax21 = plt.subplot(3,2,3)
ax22 = plt.subplot(3,2,4)
ax31 = plt.subplot(3,2,5)
ax32 = plt.subplot(3,2,6)
ax11.set_title("Schéma d'ordre 1")
ax21.set_title("Schéma d'ordre 2")
ax31.set_title("Schéma d'ordre 3")
N = 0
for k in range(6):
N += 100
tt = np.linspace(t0, tfinal, N + 1)
H.append( tt[1] - tt[0] )
yy = sol_exacte(tt)
sigma, gamma, eta = 1/2, 1/2, 1/3 # cas ordre 1
uu_1 = RK(tt,phi,y0,sigma,gamma,eta)
err_1.append( np.linalg.norm(uu_1-yy,np.inf) )
ax11.plot(tt,uu_1,label=f'Approchée avec N={N}')
sigma, gamma, eta = 1/4, 2, 1/6 # cas ordre 2
uu_2 = RK(tt,phi,y0,sigma,gamma,eta)
err_2.append( np.linalg.norm(uu_2-yy,np.inf) )
ax21.plot(tt,uu_2,label=f'Approchée avec N={N}')
sigma, gamma, eta = 2/3, 3/4, 1/3 # cas ordre 3
uu_3 = RK(tt,phi,y0,sigma,gamma,eta)
err_3.append( np.linalg.norm(uu_3-yy,np.inf) )
ax31.plot(tt,uu_3,label=f'Approchée avec N={N}')
ax11.plot(tt,yy,label='Exacte')
plt.xlabel('$t$')
plt.ylabel('$y$')
ax11.grid(True)
ax11.legend()
ax12.plot( np.log(H), np.log(err_1), 'r-o')
plt.xlabel('$\ln(h)$')
plt.ylabel('$\ln(e)$')
ax12.set_title(f'RK : ordre = {np.polyfit(np.log(H),np.log(err_1),1)[0]:1.2f}')
ax12.grid(True)
ax21.plot(tt,yy,label='Exacte')
plt.xlabel('$t$')
plt.ylabel('$y$')
ax21.grid(True)
ax21.legend()
ax22.plot( np.log(H), np.log(err_2), 'r-o')
plt.xlabel('$\ln(h)$')
plt.ylabel('$\ln(e)$')
ax22.set_title(f'RK : ordre = {np.polyfit(np.log(H),np.log(err_2),1)[0]:1.2f}')
ax22.grid(True)
ax31.plot(tt,yy,label='Exacte')
plt.xlabel('$t$')
plt.ylabel('$y$')
ax31.grid(True)
ax31.legend()
ax32.plot( np.log(H), np.log(err_3), 'r-o')
plt.xlabel('$\ln(h)$')
plt.ylabel('$\ln(e)$')
ax32.set_title(f'RK : ordre = {np.polyfit(np.log(H),np.log(err_3),1)[0]:1.2f}')
ax32.grid(True)