import numpy as np
from .config import est_pedagogique
from .utils import obtenir_h
import math
[docs]
def diff_avant(f, x, h=None, pedagogique=None):
"""
Calcule la derivee premiere par differences finies avant.
Args:
f (callable): Fonction a deriver.
x (float): Point d'evaluation.
h (float, optional): Pas de derivation.
pedagogique (bool, optional): Affiche les etapes si True.
Returns:
float: Approximation de la derivee.
"""
if h is None: h = obtenir_h(x)
val = (f(x + h) - f(x)) / h
if est_pedagogique(pedagogique):
print(f"[Pedagogique] Diff avant (h={h}): {val}")
return val
def diff_arriere(f, x, h=None, pedagogique=None):
if h is None: h = obtenir_h(x)
val = (f(x) - f(x - h)) / h
if est_pedagogique(pedagogique):
print(f"[Pedagogique] Diff arriere (h={h}): {val}")
return val
[docs]
def diff_centree(f, x, h=None, pedagogique=None):
"""
Calcule la derivee premiere par differences finies centrees.
Args:
f (callable): Fonction a deriver.
x (float): Point d'evaluation.
h (float, optional): Pas de derivation.
pedagogique (bool, optional): Affiche les etapes si True.
Returns:
float: Approximation de la derivee.
"""
if h is None: h = obtenir_h(x)
val = (f(x + h) - f(x - h)) / (2 * h)
if est_pedagogique(pedagogique):
print(f"[Pedagogique] Diff centree (h={h}): {val}")
return val
def derivee_seconde(f, x, h=None, pedagogique=None):
if h is None: h = obtenir_h(x)
val = (f(x + h) - 2 * f(x) + f(x - h)) / (h ** 2)
if est_pedagogique(pedagogique):
print(f"[Pedagogique] Derivee seconde (h={h}): {val}")
return val
def derivee_troisieme(f, x, h=None, pedagogique=None):
if h is None: h = obtenir_h(x)
val = (f(x + 2*h) - 2*f(x + h) + 2*f(x - h) - f(x - 2*h)) / (2 * h**3)
if est_pedagogique(pedagogique):
print(f"[Pedagogique] Derivee troisieme (h={h}): {val}")
return val
def derivee_nieme(f, x, n, h=None):
if h is None: h = 0.001
if n == 0: return f(x)
if n == 1: return diff_centree(f, x, h)
return (derivee_nieme(f, x+h, n-1, h) - derivee_nieme(f, x-h, n-1, h)) / (2*h)
def h_optimal(f, x, methode="centree"):
eps = np.finfo(float).eps
if methode == "centree": return eps**(1/3) * (1.0 + np.abs(x))
else: return eps**(1/2) * (1.0 + np.abs(x))
def erreur_troncature(methode, f_deriv, h):
if methode == "centree": return (h**2 / 6) * np.abs(f_deriv)
if methode in ["avant", "arriere"]: return (h / 2) * np.abs(f_deriv)
return None
def erreur_taylor(f_derivee_suivante, x, a, n):
fact = math.factorial(n + 1)
return np.abs(f_derivee_suivante / fact * (x - a)**(n + 1))