import numpy as np
from .config import est_pedagogique
from .utils import imprimer_etapes, Resultat
import math
[docs]
def differences_divisees(x, y, pedagogique=None):
"""
Calcule le tableau des differences divisees pour l'interpolation de Newton.
Args:
x (array_like): Points d'abscisse.
y (array_like): Points d'ordonnee.
pedagogique (bool, optional): Non utilise pour l'instant.
Returns:
ndarray: Coefficients de Newton.
"""
n = len(y)
coef = np.copy(y).astype(float)
for j in range(1, n):
for i in range(n - 1, j - 1, -1):
coef[i] = (coef[i] - coef[i - 1]) / (x[i] - x[i - j])
return coef
[docs]
def polynome_newton(x_pts, coeffs):
"""P(x) = a0 + a1(x-x0) + a2(x-x0)(x-x1) + ..."""
n = len(x_pts)
def poly(x):
resultat = coeffs[n-1]
for i in range(n-2, -1, -1):
resultat = resultat * (x - x_pts[i]) + coeffs[i]
return resultat
return poly
def interpolation_newton(x_pts, y_pts, pedagogique=None):
coef = differences_divisees(x_pts, y_pts, pedagogique=pedagogique)
return polynome_newton(x_pts, coef)
[docs]
def lagrange(x_pts, y_pts, pedagogique=None):
"""
Interpolation de Lagrange.
Args:
x_pts (array_like): Noeuds d'interpolation.
y_pts (array_like): Valeurs aux noeuds.
pedagogique (bool, optional): Non utilise pour l'instant.
Returns:
callable: Le polynome d'interpolation.
"""
n = len(x_pts)
def poly(x):
somme = 0
for i in range(n):
li = 1
for j in range(n):
if i != j:
li *= (x - x_pts[j]) / (x_pts[i] - x_pts[j])
somme += y_pts[i] * li
return somme
return poly
def hermite(x_pts, y_pts, dy_pts, pedagogique=None):
n = len(x_pts)
z = np.zeros(2 * n)
q = np.zeros((2 * n, 2 * n))
for i in range(n):
z[2*i] = x_pts[i]; z[2*i+1] = x_pts[i]
q[2*i][0] = y_pts[i]; q[2*i+1][0] = y_pts[i]
q[2*i+1][1] = dy_pts[i]
if i != 0:
q[2*i][1] = (q[2*i][0] - q[2*i-1][0]) / (z[2*i] - z[2*i-1])
for i in range(2, 2 * n):
for j in range(2, i + 1):
q[i][j] = (q[i][j-1] - q[i-1][j-1]) / (z[i] - z[i-j])
coeffs = np.diagonal(q)
def poly(x):
resultat = coeffs[0]
terme = 1
for i in range(2 * n - 1):
terme *= (x - z[i])
resultat += coeffs[i+1] * terme
return resultat
return poly
def erreur_interpolation(derivee_suivante, x_val, x_pts):
n = len(x_pts)
fact = math.factorial(n)
prod = np.prod([x_val - xi for xi in x_pts])
return np.abs(derivee_suivante / fact * prod)
def matrice_vandermonde(x):
return np.vander(x, increasing=True)
def base_newton(x_pts):
n = len(x_pts)
base = [lambda x: 1]
for i in range(1, n):
def b_i(x, idx=i):
res = 1
for j in range(idx):
res *= (x - x_pts[j])
return res
base.append(b_i)
return base
[docs]
def noeuds_chebyshev(a, b, n):
"""
Genere les noeuds de Chebyshev sur l'intervalle [a, b].
Args:
a (float): Borne inferieure.
b (float): Borne superieure.
n (int): Nombre de points.
Returns:
ndarray: Les points de Chebyshev.
"""
k = np.arange(1, n + 1)
noeuds = np.cos((2 * k - 1) * np.pi / (2 * n))
return 0.5 * (a + b) + 0.5 * (b - a) * noeuds
def fonction_runge(x):
return 1 / (1 + 25 * x**2)
def legendre(n):
if n == 0: return np.array([1])
if n == 1: return np.array([1, 0])
p0 = np.poly1d([1])
p1 = np.poly1d([1, 0])
for i in range(2, n + 1):
p_n = np.poly1d([(2*i - 1)/i, 0]) * p1 - ((i - 1)/i) * p0
p0, p1 = p1, p_n
return p1.coeffs