from dataclasses import dataclass import matplotlib.pyplot as plt import numpy as np @dataclass class Point: x: float y: float def interpolation_lagrange(points: list[Point], x: float, show_polynome: bool=False) -> float: """ :param points: Les points de la courbe représentant une fonction :param x: le x en entrée de la fonction où on veut interpoler :return: L'interpolation """ interpolation: float = 0. n = len(points) # nombre de points for i in range(n): term: float = 1. # 0.0 will always give 0, it's a product ! So lets put 1 # Lagrange L(x) for k in range(n): if k != i: term *= ((x - points[k].x) / (points[i].x - points[k].x)) # erreur ici, voir le chat if show_polynome: print(f'P(x) = (({x} - {points[k].x}) / ({points[i].x} - {points[k].x}))') # interpolation with a piece of Lagrange (y_i) interpolation += term * points[i].y return interpolation def calc_coef(x: list[float],y: list[float]) -> float: """ Renvois f[x0,x1,...,xk] (diff divisé de Newton) avec la relation récursive : f[x0...xk] = (f[x1...xk] - f[x0..x{k-1}] / (xk - x0) (calcul alpha) :param x: :param y: :return: """ if len(x) == 1: return y[0] elif len(x) == 2: return (y[1]-y[0]) / (x[1] - x[0]) return (calc_coef(x[1:], y[1:]) - calc_coef(x[:-1], y[:-1])) / (x[-1] - x[0]) def P_newton(x_i: list[float], y_i: list[float], x: float) -> float: """ Calcul le polynôme de Newton P_n(x) = y0 + sum_{k=1..n} a_k * prod_{j=0..k-1}(x - x_j), avec a_k = f[x0,...,xk] calculé via calc_coef() :param x_i: ensemble des x :param y_i: ensemble des y :param x: là ou on veut interpolé :return: """ p = y_i[0] e = 1. for k in range(1, len(x_i)): e *= (x - x_i[k-1]) a_k = calc_coef(x_i[:k+1], y_i[:k+1]) p += a_k * e return p def interpolation_moindre_carree(points: list[Point], x: float) -> float: interpolation = 0. pass def exercice1() -> None: points = [Point(-1,0), Point(0,-1), Point(1,0), Point(3,70)] inter_x2 = interpolation_lagrange(points, 2, True) inter_x3 = interpolation_lagrange(points, 3, True) print(f"X2={inter_x2}, X3={inter_x3}") x = np.linspace(0, 4, 300) y_lagrange = [interpolation_lagrange(points, x[i]) for i in range(len(x))] y_newton = [] for i in range(4): y_newton.append([P_newton([point.x for point in points], [point.y for point in points], i)]) print(y_lagrange) print(y_newton) # extrapolation plt.plot(x, y_lagrange) plt.title('fonction f(x) ex 1') plt.show() def exercice2() -> None: x_i = [0, np.pi / 4, np.pi / 2, (3 * np.pi) / 4, np.pi] x = [i for i in range(len(x_i))] f = lambda x : np.sin(x) results = [] for i in x: res = P_newton(x_i, [f(x_i[i]) for i in range(len(x_i))], i) print(res) results.append(res) plt.plot(results) plt.show() if __name__ == '__main__': exercice1() #exercice2()