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]:
|
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
|
# Construction de la matrice A et du vecteur y
|
||||||
T = np.array([p.x for p in points])
|
T = np.array([p.x for p in points])
|
||||||
Y = np.array([p.y 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 f: la fonction f (bien passer une fonction ou une lambda)
|
||||||
:param a: la petite borne
|
:param a: la petite borne
|
||||||
:param b: la grande borne
|
:param b: la grande borne
|
||||||
:param n: nombre de "tranche" de calcul
|
:param n: nombre de "tranche" dans l'intervalle
|
||||||
:return:
|
:return: l'approximation de la valeur de l'intervalle
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# dx = (b-a) / n
|
# largeur de chaque sous-intervalle
|
||||||
dx = (b - a) / n
|
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.
|
somme_inferieure = 0.
|
||||||
|
|
||||||
for i in range(1, n):
|
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)
|
I = (dx / 2) * (f(a) + f(b) + 2 * somme_inferieure)
|
||||||
return I
|
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:
|
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:
|
if n % 2 != 0:
|
||||||
raise ValueError(f'n must be even, got {n}')
|
raise ValueError(f'n must be even, got {n}')
|
||||||
|
|
||||||
|
# largeur de chaque sous-intervalle
|
||||||
dx = (b - a) / n
|
dx = (b - a) / n
|
||||||
|
|
||||||
somme_paire = 0.
|
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)
|
I = (dx / 3) * (f(a) + f(b) + 4 * somme_impaire + 2 * somme_paire)
|
||||||
return I
|
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
|
# Les b possibles dans Newton Cotes
|
||||||
POIDS = {
|
POIDS = {
|
||||||
2: [1/2,1/2],
|
2: [1/2,1/2],
|
||||||
@@ -65,7 +108,18 @@ POIDS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def newton_cotes(f, a: float, b: float, s: int, n: int) -> float:
|
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
|
h = (b - a) / n
|
||||||
Aj = 0.
|
Aj = 0.
|
||||||
|
|
||||||
@@ -81,6 +135,47 @@ def newton_cotes(f, a: float, b: float, s: int, n: int) -> float:
|
|||||||
return Aj
|
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():
|
def exercice1():
|
||||||
f = lambda x: x ** 2
|
f = lambda x: x ** 2
|
||||||
@@ -91,9 +186,21 @@ def exercice1():
|
|||||||
trapeze1 = trapeze_formule(g, a=0, b=np.pi, n=100)
|
trapeze1 = trapeze_formule(g, a=0, b=np.pi, n=100)
|
||||||
trapeze2 = trapeze_formule(g, a=0, b=np.pi, n=200)
|
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)
|
simpson1 = simpson(g, a=0, b=np.pi, n=100)
|
||||||
simpson2 = simpson(g, a=0, b=np.pi, n=200)
|
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)
|
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)
|
newton2 = newton_cotes(g, a=0, b=np.pi, n=200, s=4)
|
||||||
|
|
||||||
@@ -146,5 +253,5 @@ def exercice2():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
#exercice1()
|
exercice1()
|
||||||
exercice2()
|
#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