Partie IV - Calcul scientifique · Chapitre 22

Intégration numériques

3 sections de cours · fiche d'exercices corrigee

1Rectangles, trapezes, Simpson et leurs erreurs

Le probleme

Calculer \(\displaystyle I = \int_a^b f(t)\,\mathrm dt\) lorsque aucune primitive de \(f\) n'est exprimable a l'aide des fonctions usuelles, ou lorsque \(f\) n'est connue que par des valeurs tabulees.

Exemples classiques sans primitive elementaire : \(\displaystyle\int_0^1 e^{-t^2}\mathrm dt\) (loi normale), \(\displaystyle\int_0^1 \frac{\sin t}{t}\mathrm dt\) (sinus integral), \(\displaystyle\int_0^{\pi/2}\frac{\mathrm dt}{\sqrt{1-k^2\sin^2 t}}\) (integrale elliptique, periode du pendule).

Principe general des methodes de quadrature
  1. Subdiviser \([a,b]\) en \(n\) sous-intervalles de longueur \(h = \dfrac{b-a}{n}\), de bornes \(x_k = a + kh\).
  2. Sur chaque sous-intervalle, remplacer \(f\) par un polynome interpolateur de faible degre, dont on sait integrer exactement.
  3. Sommer les contributions.

Le degre du polynome determine l'ordre de la methode : constante (rectangles, ordre 1), affine (trapezes, ordre 2), quadratique (Simpson, ordre 4).

Methode des rectangles

On approche \(f\) par une constante sur chaque \([x_k, x_{k+1}]\) :

\[ \int_{x_k}^{x_{k+1}} f \approx h\,f(c_k), \qquad c_k \in \{x_k,\ x_{k+1},\ \tfrac{x_k+x_{k+1}}{2}\}. \]

def rectangles_gauche(f, a, b, n):
    """Approximation par la valeur a gauche. Ordre 1."""
    h = (b - a) / n
    return h * sum(f(a + k*h) for k in range(n))

def rectangles_droite(f, a, b, n):
    h = (b - a) / n
    return h * sum(f(a + k*h) for k in range(1, n+1))

def point_milieu(f, a, b, n):
    """Valeur au milieu de chaque sous-intervalle. Ordre 2, gratuit !"""
    h = (b - a) / n
    return h * sum(f(a + (k + 0.5)*h) for k in range(n))
Erreur des rectangles

Sur un seul sous-intervalle, la formule de Taylor donne pour le rectangle a gauche \[ \int_{x_k}^{x_k+h} f = h f(x_k) + \frac{h^2}{2}f'(x_k) + O(h^3), \] donc une erreur locale en \(O(h^2)\). En sommant sur \(n = (b-a)/h\) intervalles, l'erreur globale est en \(O(h)\) : la methode est d'ordre 1. Precisement, \[ \left|I - R_n\right| \le \frac{(b-a)h}{2}\max_{[a,b]}|f'|. \]

Le point milieu, lui, est d'ordre 2 : par symetrie, le terme en \(f'\) s'annule, et \[ \left|I - M_n\right| \le \frac{(b-a)h^2}{24}\max|f''|. \] C'est remarquable : au meme cout (une evaluation par intervalle), on gagne un ordre.

Methode des trapezes

On approche \(f\) par le segment joignant \((x_k, f(x_k))\) a \((x_{k+1}, f(x_{k+1}))\) :

\[ \int_{x_k}^{x_{k+1}} f \approx h\,\frac{f(x_k)+f(x_{k+1})}{2}. \]

En sommant et en regroupant, chaque point interieur apparait deux fois :

\[ \boxed{\;T_n = h\left(\frac{f(x_0)}{2} + \sum_{k=1}^{n-1} f(x_k) + \frac{f(x_n)}{2}\right).\;} \]

def trapezes(f, a, b, n):
    """Methode des trapezes. Ordre 2. n+1 evaluations de f."""
    h = (b - a) / n
    s = (f(a) + f(b)) / 2
    for k in range(1, n):
        s += f(a + k*h)
    return h * s
Erreur des trapezes

Si \(f\) est de classe \(\mathcal C^2\) sur \([a,b]\), il existe \(\xi \in\;]a,b[\) tel que \[ I - T_n = -\frac{(b-a)h^2}{12}f''(\xi), \qquad\text{donc}\qquad |I - T_n| \le \frac{(b-a)h^2}{12}\max_{[a,b]}|f''|. \] La methode est d'ordre 2 : diviser \(h\) par 2 divise l'erreur par 4.

Idee de la demonstration (sur un intervalle)

Sur \([x_k, x_{k+1}]\), on pose \(e(h) = \int_{x_k}^{x_k+h} f - \frac h2(f(x_k)+f(x_k+h))\). On a \(e(0) = 0\), et en derivant deux fois par rapport a \(h\) : \(e''(h) = -\frac h2 f''(x_k+h)\). Une double integration et le theoreme des accroissements finis donnent \(e(h) = -\frac{h^3}{12}f''(\xi_k)\). En sommant sur les \(n\) intervalles et en utilisant le theoreme des valeurs intermediaires pour \(f''\), on obtient la formule globale.

Signe de l'erreur : si \(f\) est convexe (\(f'' \ge 0\)), les cordes sont au-dessus de la courbe, donc \(T_n \ge I\). Les trapezes surestiment une integrale de fonction convexe, et le point milieu la sous-estime.

Methode de Simpson

On approche \(f\) par la parabole passant par \((x_k, f(x_k))\), \((x_{k+1/2}, f(x_{k+1/2}))\) et \((x_{k+1}, f(x_{k+1}))\) :

\[ \int_{x_k}^{x_{k+1}} f \approx \frac{h}{6}\Bigl(f(x_k) + 4f(x_{k+1/2}) + f(x_{k+1})\Bigr). \]

def simpson(f, a, b, n):
    """Methode de Simpson composee. n doit etre PAIR. Ordre 4."""
    if n % 2 != 0:
        n += 1
    h = (b - a) / n
    s = f(a) + f(b)
    s += 4 * sum(f(a + k*h) for k in range(1, n, 2))     # indices impairs
    s += 2 * sum(f(a + k*h) for k in range(2, n, 2))     # indices pairs
    return h * s / 3
Erreur de Simpson

\[ I - S_n = -\frac{(b-a)h^4}{180}f^{(4)}(\xi), \qquad |I - S_n| \le \frac{(b-a)h^4}{180}\max|f^{(4)}|. \] La methode est d'ordre 4 : diviser \(h\) par 2 divise l'erreur par 16.

Fait remarquable : bien que construite sur des paraboles, la methode de Simpson est exacte pour les polynomes de degre 3. Le terme d'erreur en \(f^{(3)}\) s'annule par symetrie ; c'est un degre gagne gratuitement.

assert abs(simpson(lambda x: x**3, 0, 1, 2) - 0.25) < 1e-15   # EXACT
assert abs(simpson(lambda x: x**4, 0, 1, 2) - 0.2) > 1e-6     # plus exact
Relation avec trapezes et point milieu

Simpson est la combinaison \(S = \dfrac{T + 2M}{3}\), ou \(T\) est la formule des trapezes et \(M\) celle du point milieu sur le meme decoupage. C'est aussi l'extrapolation de Richardson de la formule des trapezes : \[ S_{2n} = \frac{4T_{2n} - T_n}{3}. \] On elimine ainsi le terme d'erreur en \(h^2\), gagnant deux ordres d'un coup (le developpement d'Euler-Maclaurin des trapezes ne contient que des puissances paires).

2Visualisation interactive et comparaison

Methodes de quadrature : visualisation de l'erreur

Comparaison des methodes

MethodeFormule localeOrdreErreur Exacte pour
Rectangles (gauche/droite)\(h f(x_k)\)1 \(\frac{(b-a)h}{2}\max|f'|\)degre 0
Point milieu\(h f(x_{k+1/2})\)2 \(\frac{(b-a)h^2}{24}\max|f''|\)degre 1
Trapezes\(\frac h2(f_k+f_{k+1})\)2 \(\frac{(b-a)h^2}{12}\max|f''|\)degre 1
Simpson\(\frac h6(f_k+4f_{k+1/2}+f_{k+1})\)4 \(\frac{(b-a)h^4}{180}\max|f^{(4)}|\)degre 3
Trois observations
  • Le point milieu est deux fois plus precis que les trapezes (constante 1/24 contre 1/12) pour le meme nombre d'evaluations. Il est pourtant moins enseigne.
  • Les erreurs du point milieu et des trapezes sont de signes opposes : leur combinaison \(\frac{T + 2M}{3}\) elimine le terme dominant et donne Simpson.
  • Une methode a \(m\) points est generalement exacte jusqu'au degre \(m-1\) ; les formules symetriques gagnent un degre supplementaire.
Comparaison numerique
from math import exp, e

I = e - 1
print(f"{'n':>6}{'rectangles':>16}{'milieu':>16}{'trapezes':>16}{'Simpson':>16}")
for n in (2, 4, 8, 16, 32, 64):
    r = abs(rectangles_gauche(exp, 0, 1, n) - I)
    m = abs(point_milieu(exp, 0, 1, n) - I)
    t = abs(trapezes(exp, 0, 1, n) - I)
    s = abs(simpson(exp, 0, 1, n) - I)
    print(f"{n:>6}{r:>16.3e}{m:>16.3e}{t:>16.3e}{s:>16.3e}")
     n      rectangles          milieu        trapezes         Simpson
     2       4.259e-01       2.146e-02       4.312e-02       5.792e-05
     4       2.281e-01       5.363e-03       1.076e-02       3.587e-06
     8       1.181e-01       1.341e-03       2.688e-03       2.232e-07
    16       6.008e-02       3.352e-04       6.719e-04       1.393e-08
    32       3.030e-02       8.380e-05       1.680e-04       8.703e-10
    64       1.522e-02       2.095e-05       4.199e-05       5.439e-11

Les rapports d'une ligne a la suivante valent 2, 4, 4 et 16 : ils confirment les ordres 1, 2, 2 et 4. Avec seulement 64 intervalles, Simpson atteint \(5\cdot10^{-11}\) la ou les rectangles plafonnent a \(1{,}5\cdot10^{-2}\) : neuf ordres de grandeur d'ecart.

3Methodes adaptatives, integrales impropres et applications

Methode adaptative

Principe

Un pas uniforme est inefficace si \(f\) varie beaucoup sur une petite portion de l'intervalle et peu ailleurs. Une methode adaptative subdivise recursivement, et ne raffine que la ou l'erreur estimee est trop grande.

L'estimation d'erreur repose sur la comparaison entre une approximation grossiere et une approximation fine : pour Simpson d'ordre 4, \[ |I - S_{\text{fine}}| \approx \frac{|S_{\text{fine}} - S_{\text{grossiere}}|}{15}. \]

def simpson_simple(f, a, b):
    """Simpson sur un seul intervalle : 3 evaluations."""
    m = (a + b) / 2
    return (b - a) / 6 * (f(a) + 4*f(m) + f(b))

def adaptative(f, a, b, eps=1e-10, profondeur=50):
    """Simpson adaptative recursive. Renvoie (valeur, nombre d'evaluations)."""
    compteur = [0]
    def g(x):
        compteur[0] += 1
        return f(x)

    def aux(a, b, eps, entier, prof):
        m = (a + b) / 2
        gauche  = simpson_simple(g, a, m)
        droite  = simpson_simple(g, m, b)
        if prof <= 0 or abs(gauche + droite - entier) <= 15 * eps:
            # extrapolation de Richardson : on ajoute l'estimation d'erreur
            return gauche + droite + (gauche + droite - entier) / 15
        return (aux(a, m, eps/2, gauche, prof-1)
                + aux(m, b, eps/2, droite, prof-1))

    total = simpson_simple(g, a, b)
    return aux(a, b, eps, total, profondeur), compteur[0]

from math import sin, exp, pi

# fonction reguliere : peu d'evaluations
print(adaptative(sin, 0, pi))                    # (2.0000000000, ~ 40 evaluations)

# fonction a variation localisee : le raffinement se concentre au bon endroit
f = lambda x: exp(-100 * (x - 0.3)**2)           # gaussienne tres piquee
v, ev = adaptative(f, 0, 1, 1e-12)
print(f"valeur {v:.12f}, {ev} evaluations")

# comparaison a pas uniforme
for n in (100, 1000, 10000):
    print(f"  Simpson uniforme n = {n:>6} : {simpson(f, 0, 1, n):.12f}")

Sur une gaussienne piquee, la methode adaptative atteint \(10^{-12}\) avec quelques centaines d'evaluations, la ou une methode uniforme en demanderait des dizaines de milliers : elle place les points la ou ils sont utiles.

Integrales impropres

Les methodes de base echouent
from math import sqrt, log

# 1. singularite integrable : 1/sqrt(x) sur ]0, 1]
trapezes(lambda x: 1/sqrt(x), 0, 1, 1000)     # ZeroDivisionError en x = 0
# 2. borne infinie
trapezes(lambda x: exp(-x*x), 0, float("inf"), 1000)   # impossible
Trois techniques

1. Point milieu : il n'evalue jamais aux bornes, donc tolere une singularite integrable aux extremites.

print(point_milieu(lambda x: 1/sqrt(x), 0, 1, 10**6))   # 1.999... (exact : 2)

La convergence est toutefois degradee (ordre \(1/2\) au lieu de 2) car \(f''\) n'est pas bornee.

2. Changement de variable pour absorber la singularite. Pour \(\int_0^1 \frac{\mathrm dx}{\sqrt x}\), on pose \(x = t^2\) :

# int_0^1 dx/sqrt(x) = int_0^1 2 dt  : la singularite a DISPARU
print(trapezes(lambda t: 2.0, 0, 1, 10))     # 2.0 exactement

3. Troncature ou changement de variable pour une borne infinie. Pour \(\int_0^{+\infty} e^{-x^2}\mathrm dx = \frac{\sqrt\pi}{2}\) :

from math import sqrt, pi, exp

# a) troncature : l'integrande est negligeable au-dela de 6
print(simpson(lambda x: exp(-x*x), 0, 6, 1000), sqrt(pi)/2)

# b) changement de variable x = t/(1-t), qui envoie [0,1[ sur [0, +inf[
def g(t):
    if t >= 1: return 0.0
    x = t / (1 - t)
    return exp(-x*x) / (1 - t)**2        # facteur dx/dt
print(point_milieu(g, 0, 1, 10000), sqrt(pi)/2)

La troncature exige de majorer la queue : ici \(\int_6^{+\infty} e^{-x^2}\mathrm dx < \frac{e^{-36}}{12} \approx 10^{-17}\), donc negligeable devant la precision machine.

Application — fonctions speciales

from math import exp, sqrt, pi, sin

def erf(x, n=2000):
    """Fonction d'erreur : erf(x) = 2/sqrt(pi) * int_0^x exp(-t^2) dt."""
    return 2/sqrt(pi) * simpson(lambda t: exp(-t*t), 0, x, n)

def Si(x, n=2000):
    """Sinus integral : Si(x) = int_0^x sin(t)/t dt.  (prolonge par 1 en 0)"""
    f = lambda t: 1.0 if t == 0 else sin(t)/t
    return simpson(f, 0, x, n)

def periode_pendule(theta0, L=1.0, g=9.81, n=2000):
    """Periode exacte d'un pendule simple d'amplitude theta0 (integrale elliptique)."""
    k = sin(theta0 / 2)
    integrale = simpson(lambda t: 1/sqrt(1 - k*k*sin(t)**2), 0, pi/2, n)
    return 4 * sqrt(L/g) * integrale

import math
assert abs(erf(1) - math.erf(1)) < 1e-12
print(f"Si(1)  = {Si(1):.10f}")                    # 0.9460830704
print(f"petites oscillations : {2*pi*sqrt(1/9.81):.6f} s")
for a in (10, 30, 60, 90, 150):
    T = periode_pendule(math.radians(a))
    print(f"  amplitude {a:>3} deg : T = {T:.6f} s "
          f"(+{100*(T/(2*pi*sqrt(1/9.81)) - 1):.2f} %)")
petites oscillations : 2.006066 s
  amplitude  10 deg : T = 2.007888 s (+0.09 %)
  amplitude  30 deg : T = 2.023420 s (+0.86 %)
  amplitude  60 deg : T = 2.077848 s (+3.58 %)
  amplitude  90 deg : T = 2.178146 s (+8.58 %)
  amplitude 150 deg : T = 2.751594 s (+37.16 %)

L'approximation des petites oscillations \(T \approx 2\pi\sqrt{L/g}\), universellement enseignee, n'est valable qu'a 1 % pres jusqu'a 30 degres. A 150 degres, l'erreur atteint 37 % : le calcul numerique donne acces au regime non lineaire, inaccessible analytiquement.

L'essentiel du chapitre

  • Rectangles : ordre 1. Point milieu et trapezes : ordre 2. Simpson : ordre 4.
  • Doubler \(n\) divise l'erreur par \(2^p\) ou \(p\) est l'ordre : c'est le test de validation.
  • Formule des trapezes : \(T_n = h\left(\frac{f_0}{2} + \sum_{k=1}^{n-1}f_k + \frac{f_n}{2}\right)\).
  • Simpson est exacte jusqu'au degre 3, et vaut \(\frac{4T_{2n}-T_n}{3}\).
  • Trapezes surestiment et point milieu sous-estime une integrale de fonction convexe.
  • Le point milieu tolere une singularite aux bornes ; sinon, changer de variable.
  • Les methodes adaptatives concentrent les evaluations la ou \(f\) varie.
Fiche d'exercices — chapitre 22Enonces gradues, du calcul d'application au niveau concours, avec corriges detailles.
Ouvrir la fiche →