140 lines
3.8 KiB
Python
140 lines
3.8 KiB
Python
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
|
|
|
|
def euler_ex1(f, n: int, h: float, x_0: float, y_0: float) -> tuple[list[float], list[float]]:
|
|
"""
|
|
|
|
:param f: la fonction f (ou y)
|
|
:param n: jusqu'où va le calcul (le nombre d'itérations)
|
|
:param h: le pas de chaque itération
|
|
:param x_0: dans la condition initiale, c'est la valeur passée en entrée de f
|
|
:param y_0: dans la condition initiale, c'est la valeur de sortie de f.
|
|
:return:
|
|
"""
|
|
results_x = [x_0]
|
|
results_y = [y_0]
|
|
# h c'est delta_x
|
|
x = x_0
|
|
y = y_0
|
|
for i in range(n):
|
|
if i < 4:
|
|
x = x + h
|
|
y = y + h * f(x, y)
|
|
else:
|
|
h = .3
|
|
x = x + h
|
|
y = y + h * f(x, y)
|
|
results_x.append(x)
|
|
results_y.append(y)
|
|
|
|
return results_x, results_y
|
|
|
|
|
|
def runge_kutta(f, n: int, h: float, x_0: float, y_0: float) -> tuple[list[float], list[float]]:
|
|
results_x = [x_0]
|
|
results_y = [y_0]
|
|
x = x_0
|
|
y = y_0
|
|
for i in range(n):
|
|
if i < 4:
|
|
k_1 = f(x, y)
|
|
k_2 = f(x + (h / 2), y + (h / 2) * k_1)
|
|
x = x + h
|
|
y = y + h * k_2
|
|
else:
|
|
h = .3
|
|
k_1 = f(x, y)
|
|
k_2 = f(x + (h / 2), y + (h / 2) * k_1)
|
|
x = x + h
|
|
y = y + h * k_2
|
|
results_x.append(x)
|
|
results_y.append(y)
|
|
|
|
return results_x, results_y
|
|
|
|
|
|
def taylor(f, f_derive_x, f_derive_y, n: int, h: float, x_0: float, y_0: float) -> tuple[list[float], list[float]]:
|
|
results_x = [x_0]
|
|
results_y = [y_0]
|
|
|
|
x = x_0
|
|
y = y_0
|
|
|
|
for i in range(n):
|
|
if i < 4:
|
|
x = x + h
|
|
y = y + h * f(x, y) + (h ** 2) / 2 * (f_derive_x(x, y) + f_derive_y(x, y) * f(x, y))
|
|
else:
|
|
h = .3
|
|
x = x + h
|
|
y = y + h * f(x, y) + (h ** 2) / 2 * (f_derive_x(x, y) + f_derive_y(x, y) * f(x, y))
|
|
results_x.append(x)
|
|
results_y.append(y)
|
|
|
|
return results_x, results_y
|
|
|
|
|
|
def exercice1() -> None:
|
|
f = lambda x, y: -2 * x * y + 1
|
|
f_derive_x = lambda x, y: -2 * y + 1
|
|
f_derive_y = lambda x, y: -2 * x + 1
|
|
|
|
results_x_euler, results_y_euler = euler(f, n=5, x_0=0, y_0=1, h=.2)
|
|
results_x_runge, results_y_runge = runge_kutta(f, n=5, x_0=0, y_0=1, h=.2)
|
|
results_x_taylor, results_y_taylor = taylor(f, f_derive_x, f_derive_y, 5, x_0=0, y_0=1, h=.2)
|
|
|
|
plt.plot(results_x_euler, results_y_euler, color='green')
|
|
plt.plot(results_x_runge, results_y_runge, color='red')
|
|
plt.plot(results_x_taylor, results_y_taylor, color='blue')
|
|
|
|
plt.title('La giga fonction pour les equations différentielles. (mieux que le sex garanti 3 ans)')
|
|
plt.show()
|
|
|
|
|
|
def euler(f, n: int, h: float, x_0: float, y_0: float) -> tuple[list[float], list[float]]:
|
|
"""
|
|
|
|
:param f: la fonction f (ou y)
|
|
:param n: jusqu'où va le calcul (le nombre d'itérations)
|
|
:param h: le pas de chaque itération
|
|
:param x_0: dans la condition initiale, c'est la valeur passée en entrée de f
|
|
:param y_0: dans la condition initiale, c'est la valeur de sortie de f.
|
|
:return:
|
|
"""
|
|
results_x = [x_0]
|
|
results_y = [y_0]
|
|
# h c'est delta_x
|
|
x = x_0
|
|
y = y_0
|
|
for i in range(n):
|
|
y = y + h * x
|
|
x = x + h * f(x, y)
|
|
results_x.append((i + 1) * h)
|
|
results_y.append(y)
|
|
|
|
return results_x, results_y
|
|
|
|
|
|
def exercice2() -> None:
|
|
g = 9.8 # c'est une constante. (intensité de la pesanteur)
|
|
dt = .01 # intervale de temps
|
|
c_1 = np.pi / 2
|
|
c_2 = 0
|
|
|
|
f = lambda x, y: -x - g * np.sin(y)
|
|
|
|
results_x, results_y = euler(f, n=int(15 / dt), h=dt, x_0=c_1, y_0=c_2)
|
|
plt.plot(results_x, results_y)
|
|
plt.xlabel('t')
|
|
plt.ylabel('teta')
|
|
plt.title('le mouvement du pendule')
|
|
plt.show()
|
|
|
|
print(f'Solution pour t = 15 : {results_y[14]}')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
#exercice1()
|
|
exercice2()
|