Refactor: Ajoute de la documentation et de nouvelle implémentation pour les méthodes de calcul d'intervalle
This commit is contained in:
6
tp6.py
6
tp6.py
@@ -123,6 +123,12 @@ def exercice2() -> None:
|
||||
|
||||
|
||||
def moindre_carre(points: list[Point]) -> np.ndarray[np.float64]:
|
||||
"""
|
||||
|
||||
:param points:
|
||||
:return: Le vecteur contenant les coefficients du polynome
|
||||
"""
|
||||
|
||||
# Construction de la matrice A et du vecteur y
|
||||
T = np.array([p.x for p in points])
|
||||
Y = np.array([p.y for p in points])
|
||||
|
||||
121
tp7.py
121
tp7.py
@@ -10,14 +10,14 @@ def trapeze_formule(f, a: float, b: float, n: int) -> float:
|
||||
:param f: la fonction f (bien passer une fonction ou une lambda)
|
||||
:param a: la petite borne
|
||||
:param b: la grande borne
|
||||
:param n: nombre de "tranche" de calcul
|
||||
:return:
|
||||
:param n: nombre de "tranche" dans l'intervalle
|
||||
:return: l'approximation de la valeur de l'intervalle
|
||||
"""
|
||||
|
||||
# dx = (b-a) / n
|
||||
# largeur de chaque sous-intervalle
|
||||
dx = (b - a) / n
|
||||
|
||||
# somme_inferieure = sum de i = 1 jusqu'a n - 1 faire f(xi)
|
||||
# la somme des valeurs de f aux points entre a et b, f(a) f(b) exclus
|
||||
somme_inferieure = 0.
|
||||
|
||||
for i in range(1, n):
|
||||
@@ -28,11 +28,37 @@ def trapeze_formule(f, a: float, b: float, n: int) -> float:
|
||||
I = (dx / 2) * (f(a) + f(b) + 2 * somme_inferieure)
|
||||
return I
|
||||
|
||||
def trapeze_version_numpy(f, a: float, b: float, n: int) -> float:
|
||||
"""
|
||||
|
||||
:param f: la fonction f (bien passer une fonction ou une lambda)
|
||||
:param a: la petite borne
|
||||
:param b: la grande borne
|
||||
:param n: nombre de "tranche" dans l'intervalle
|
||||
:return: l'approximation de la valeur de l'intervalle
|
||||
"""
|
||||
|
||||
# largeur de chaque sous-intervalle
|
||||
dx = (b - a) / n
|
||||
x = np.linspace(a, b, n+1)
|
||||
y = f(x)
|
||||
return dx * (np.sum(y) - 0.5*(y[0] + y[-1]))
|
||||
|
||||
|
||||
def simpson(f, a: float, b: float, n: int) -> float:
|
||||
"""
|
||||
|
||||
:param f: la fonction f(x)
|
||||
:param a: la petite borne
|
||||
:param b: la grande borne
|
||||
:param n: nombre de "tranche" dans l'intervalle
|
||||
:return: l'approximation de la valeur de l'intervalle
|
||||
"""
|
||||
|
||||
if n % 2 != 0:
|
||||
raise ValueError(f'n must be even, got {n}')
|
||||
|
||||
# largeur de chaque sous-intervalle
|
||||
dx = (b - a) / n
|
||||
|
||||
somme_paire = 0.
|
||||
@@ -48,6 +74,23 @@ def simpson(f, a: float, b: float, n: int) -> float:
|
||||
I = (dx / 3) * (f(a) + f(b) + 4 * somme_impaire + 2 * somme_paire)
|
||||
return I
|
||||
|
||||
|
||||
def simpson_numpy(f, a: float, b: float, n: int) -> float:
|
||||
if n % 2 != 0:
|
||||
raise ValueError(f'n must be even, got {n}')
|
||||
|
||||
# largeur de chaque sous-intervalle
|
||||
dx = (b - a) / n
|
||||
x = np.linspace(a, b, n + 1)
|
||||
y = f(x)
|
||||
|
||||
coefficients = np.ones(n + 1) # Crée un tableau de 1.0 de taille n+1
|
||||
coefficients[1:n:2] = 4 # Remplace les indices impairs (1, 3, 5, ...) par 4
|
||||
coefficients[2:n:2] = 2 # Remplace les indices pairs (2, 4, 6, ...) par 2
|
||||
|
||||
return (dx / 3) * np.sum(coefficients * y)
|
||||
|
||||
|
||||
# Les b possibles dans Newton Cotes
|
||||
POIDS = {
|
||||
2: [1/2,1/2],
|
||||
@@ -65,7 +108,18 @@ POIDS = {
|
||||
}
|
||||
|
||||
def newton_cotes(f, a: float, b: float, s: int, n: int) -> float:
|
||||
weights = POIDS[s+1] # Poids pour l'ordre s
|
||||
"""
|
||||
|
||||
:param f: la fonction f(x)
|
||||
:param a: la petite borne
|
||||
:param b: la grande borne
|
||||
:param s: l'ordre (faire +1 pour savoir quel poid utiliser) Cela détermine comme on approxime la courbe de la fonction
|
||||
Une courbe (méthode des trapèzes), un polynôme de deg. 2 (Simpson), etc.
|
||||
:param n: Nombre de "tranche" dans l'intervalle
|
||||
:return: l'approximation de la valeur de l'intervalle
|
||||
"""
|
||||
|
||||
weights = POIDS[s+1] # Poids pour l'ordre "s"
|
||||
h = (b - a) / n
|
||||
Aj = 0.
|
||||
|
||||
@@ -81,6 +135,47 @@ def newton_cotes(f, a: float, b: float, s: int, n: int) -> float:
|
||||
return Aj
|
||||
|
||||
|
||||
def newton_cotes_numpy(f, a: float, b: float, s: int, n: int) -> float:
|
||||
"""
|
||||
Approximation de l'intégrale de f sur [a, b] par la formule de Newton-Cotes d'ordre s.
|
||||
|
||||
:param f: Fonction à intégrer.
|
||||
:param a: Borne inférieure.
|
||||
:param b: Borne supérieure.
|
||||
:param s: Ordre de la formule (1: trapèzes, 2: Simpson, etc.).
|
||||
:param n: Nombre de sous-intervalles (doit être divisible par s pour les formules fermées).
|
||||
:return: Approximation de l'intégrale.
|
||||
"""
|
||||
|
||||
if n % s != 0:
|
||||
raise ValueError(f'n must be a multiple of s, got s = {s} and n = {n}')
|
||||
|
||||
# b_i dans le tableau
|
||||
weights_by_orders = {
|
||||
2: [1 / 2, 1 / 2], # trapèzes
|
||||
3: [1 / 6, 4 / 6, 1 / 6], # simpson
|
||||
4: [1 / 8, 3 / 8, 3 / 8, 1 / 8], # simpson 3/8
|
||||
5: [
|
||||
7 / 90,
|
||||
32 / 90,
|
||||
12 / 90,
|
||||
32 / 90,
|
||||
7 / 90,
|
||||
], # bool
|
||||
6: [19 / 288, 75 / 288, 50 / 288, 50 / 288, 75 / 255, 19 / 255],
|
||||
7: [41 / 840, 216 / 840, 27 / 840, 272 / 840, 27 / 840, 216 / 840, 41 / 840]
|
||||
}
|
||||
|
||||
weights = weights_by_orders[s+1]
|
||||
h = (b - a) / n
|
||||
x = np.linspace(a, b, n * s + 1) # Tous les points d'évaluation
|
||||
y = f(x)
|
||||
|
||||
# Applique les poids de manière glissante sur chaque sous-intervalle
|
||||
return np.sum(
|
||||
np.convolve(y, weights[::-1], mode='valid') * (h / (s + 1)) # Convolution pour appliquer les poids
|
||||
)
|
||||
|
||||
|
||||
def exercice1():
|
||||
f = lambda x: x ** 2
|
||||
@@ -91,9 +186,21 @@ def exercice1():
|
||||
trapeze1 = trapeze_formule(g, a=0, b=np.pi, n=100)
|
||||
trapeze2 = trapeze_formule(g, a=0, b=np.pi, n=200)
|
||||
|
||||
giga_trapeze1 = trapeze_version_numpy(g, 0, np.pi, 100)
|
||||
giga_trapeze2 = trapeze_version_numpy(g, 0, np.pi, 200)
|
||||
|
||||
print(f'VERSION MOI {trapeze1}, VERSION CHAT {giga_trapeze1}')
|
||||
print(f'VERSION MOI {trapeze2}, VERSION CHAT {giga_trapeze2}')
|
||||
|
||||
simpson1 = simpson(g, a=0, b=np.pi, n=100)
|
||||
simpson2 = simpson(g, a=0, b=np.pi, n=200)
|
||||
|
||||
giga_simpson1 = simpson_numpy(g, 0, np.pi, 100)
|
||||
giga_simpson2 = simpson_numpy(g, 0, np.pi, 200)
|
||||
|
||||
print(f'MOI: {simpson1}, CHAT : {giga_simpson1}')
|
||||
print(f'MOI: {simpson2}, CHAT : {giga_simpson2}')
|
||||
|
||||
newton1 = newton_cotes(g, a=0, b=np.pi, n=100, s=4)
|
||||
newton2 = newton_cotes(g, a=0, b=np.pi, n=200, s=4)
|
||||
|
||||
@@ -146,5 +253,5 @@ def exercice2():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
#exercice1()
|
||||
exercice2()
|
||||
exercice1()
|
||||
#exercice2()
|
||||
|
||||
26
tp8.py
Normal file
26
tp8.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def euler(f, n: int, delta_x: float, x_0: float, y_0: float) -> list[float]:
|
||||
results = []
|
||||
|
||||
x = x_0
|
||||
y = y_0
|
||||
for i in range(n):
|
||||
x = x + delta_x
|
||||
y = y + delta_x * f(x, y)
|
||||
results.append(y)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def exercice1() -> None:
|
||||
f = lambda x, y: -2 * x * y + 1
|
||||
results = euler(f, n=20, x_0=0, y_0=1, delta_x=.2)
|
||||
plt.plot(results)
|
||||
plt.title('Euler')
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
exercice1()
|
||||
Reference in New Issue
Block a user