Règles de Simpson

Introduction

Les règles de Simpson sont des méthodes numériques pour approximer des intégrales. Les règles sont particulièrement bien adaptées aux fonctions consignées dans tableau, où seulement des points à intervalles réguliers sont disponibles.

En stabilité, ces approximations servent à calculer l’aire sous la courbe du bras de levier GZ. Cette aire est une mesure de caractérisant le roulis d’une navire.

Dans cette section, nous verrons les trois règles de Simpson, leur origine et leur application à des calculs concrets de stabilité.

Les règles de Simpson estiment l’intégrale d’une fonction \(f(x)\) quelconque à l’aide d’expressions quadratiques (\(ax^2+bx+c\)) ou cubiques (\(ax^3+bx^2+cx+d\)). On approxime des intervalles de la fonction par en choisissant les coefficients (\(a,b, c, d\)) de ces fonctions. Si les intervalles sont de petite taille, alors l’approximation est bonne.

Ci-dessous, la Figure 1 illustre la fonction \(\sin(x)\) sur l’intervalle \([0, \pi]\). Elle montre également en couleur des approximations quadratiques successives de l’aire sous la courbe sur des intervalles égaux. Chaque intervalle (de couleur différente) est approximé par une fonction quadratique différente. Ici, les approximations sont tellement bonnes qu’il n’est pas possible de distinguer la courbe originale des aproximations.

Voir le calcul.
import numpy as np
import matplotlib.pyplot as plt

def illustrate_simpsons_6_areas():
    # 1. Configuration
    f = lambda x: np.sin(x)
    a, b = 0, np.pi
    
    # Pour avoir 6 aires (segments), il nous faut 6 * 2 = 12 intervalles
    n_intervalles = 12 
    n_segments = n_intervalles // 2
    
    # Points pour la courbe lisse
    x_fine = np.linspace(a, b, 500)
    y_fine = f(x_fine)
    
    # Points de subdivision (les nœuds)
    x_nodes = np.linspace(a, b, n_intervalles + 1)
    y_nodes = f(x_nodes)
    
    # 2. Création de la figure
    fig, ax = plt.subplots(figsize=(8, 7*2/3))
    ax.set_facecolor('#f8f9fa')
    
    # 3. Calcul et dessin des 6 segments paraboliques
    # On génère 6 couleurs distinctes
    colors = plt.cm.viridis(np.linspace(0.1, 0.9, n_segments))
    
    for i in range(0, n_intervalles, 2):
        # Index du segment (de 0 à 5)
        seg_idx = i // 2
        
        # On prend les 3 points pour la parabole
        x_triplet = x_nodes[i:i+3]
        y_triplet = y_nodes[i:i+3]
        
        # Interpolation parabolique
        poly_coeffs = np.polyfit(x_triplet, y_triplet, 2)
        p = np.poly1d(poly_coeffs)
        
        # Échantillonnage pour la courbe du segment
        x_parabole = np.linspace(x_triplet[0], x_triplet[2], 100)
        y_parabole = p(x_parabole)
        
        # Dessin de l'aire du segment
        ax.fill_between(x_parabole, 0, y_parabole, color=colors[seg_idx], 
                        alpha=0.5, label=f'Segment {seg_idx + 1}' if seg_idx < 6 else "")
        
        # Dessin de la ligne de la parabole
        ax.plot(x_parabole, y_parabole, color=colors[seg_idx], linewidth=2, zorder=4)

    # 4. La fonction originale (sin x) en rouge
    ax.plot(x_fine, y_fine, color='crimson', linewidth=2.5, label='$f(x) = \sin(x)$', zorder=5)
    
    # 5. Mise en forme
    ax.set_title(f"Règle de Simpson : 6 segments paraboliques distincts\n(Basé sur {n_intervalles} intervalles)", 
                 fontsize=14, fontweight='bold')
    ax.set_xlabel("x", fontsize=12)
    ax.set_ylabel("f(x)", fontsize=12)
    
    ax.axhline(0, color='black', linewidth=0.8)
    ax.grid(True, linestyle=':', alpha=0.6)
    
    # Légende avec colonnes pour ne pas être trop longue
    ax.legend(loc='upper right', frameon=True, facecolor='white', ncol=2, fontsize='small')
    
    # Limites et ticks
    ax.set_xlim(a - 0.2, b + 0.2)
    ax.set_ylim(-0.1, 1.2)
    ax.set_xticks([0, np.pi/2, np.pi])
    ax.set_xticklabels(['0', r'$\pi/2$', r'$\pi$'])

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    illustrate_simpsons_6_areas()
Figure 1: Les approximations de Simpson sont proches de la courbe réelle (en rouge).

Les règles de Simpson sont simples d’application et relativement faciles à mémoriser. Dans le cadre de l’étude de la stabilité, leur usage est parfaitement adapté aux livrets de stabilité. À titre d’exemple, une courbe de stabilité peut être représentée par le Tableau 1. On note des intervalles égaux et de 10° et les valeurs de la fonction à ces valeurs.

Tableau 1: Une courbe GZ (fictive) sous forme de tableau
\(\theta\) 0° 10° 20° 30° 40°
\(GZ(\theta)\) (m) 0 0.25 0.35 0.40 0.55

Les règles de Simpson n’épousent pas toujours les fonctions aussi bien que ce que suggère la Figure 1. La Figure 2 donne un exemple où le les intervalles fixes dégrade la performance de l’approximation. Il y a une différence importante entre l’approximation de Simpson et la fonction réelle. Lorsqu’on peut choisir les intervalles, il existe de meilleures approximations que les règles de Simpson.

Voir le calcul.
import numpy as np
import matplotlib.pyplot as plt

def illustrate_simpson_error():
    # 1. Configuration de la fonction "non-quadratique"
    # On ajoute une haute fréquence pour créer des oscillations que la parabole ne peut suivre
    f = lambda x: np.sin(x) + 0.5 * np.sin(5 * x)
    a, b = 0, np.pi
    
    # 2. Points de subdivision
    # 7 points de subdivision (nœuds) -> 6 intervalles -> 3 segments Simpson
    n_points = 7
    x_nodes = np.linspace(a, b, n_points)
    y_nodes = f(x_nodes)
    
    # Points pour la courbe lisse (haute résolution)
    x_fine = np.linspace(a, b, 1000)
    y_fine = f(x_fine)
    
    # 3. Création de la figure
    fig, ax = plt.subplots(figsize=(8, 7*2/3))
    ax.set_facecolor('#f8f9fa')
    
    # 4. Calcul et dessin des segments paraboliques
    # On utilise une colormap 'Set3' qui offre des couleurs distinctes et douces
    colors = plt.cm.Set3(np.linspace(0, 1, (n_points - 1) // 2))
    
    for i in range(0, n_points - 1, 2):
        seg_idx = i // 2
        
        # Trois points pour définir la parabole de Simpson
        x_triplet = x_nodes[i : i+3]
        y_triplet = y_nodes[i : i+3]
        
        # Interpolation parabolique (degré 2)
        poly_coeffs = np.polyfit(x_triplet, y_triplet, 2)
        p = np.poly1d(poly_coeffs)
        
        # Création d'un échantillonnage fin pour le segment
        x_parabole = np.linspace(x_triplet[0], x_triplet[2], 100)
        y_parabole = p(x_parabole)
        
        # Dessin de l'aire translucide
        ax.fill_between(x_parabole, 0, y_parabole, color=colors[seg_idx], 
                        alpha=0.5, label=f'Segment Simpson {seg_idx + 1}' if seg_idx == 0 else "")
        
        # Dessin de la ligne de la parabole
        ax.plot(x_parabole, y_parabole, color=colors[seg_idx], linewidth=2.5, zorder=4)
        
        # Optionnel : marquer les nœuds pour la clarté
        ax.scatter(x_triplet, y_triplet, color='black', s=30, zorder=5)

    # 5. Dessin de la fonction originale (la courbe réelle)
    # On utilise Crimson pour un contraste maximal avec les couleurs pastel des segments
    ax.plot(x_fine, y_fine, color='crimson', linewidth=2, label='Fonction réelle $f(x)$', zorder=6)
    
    # 6. Mise en forme esthétique
    ax.set_title("Erreur d'approximation par la règle de Simpson\n(7 points de subdivision $\\rightarrow$ 3 segments paraboliques)", 
                 fontsize=15, fontweight='bold')
    ax.set_xlabel("$x$", fontsize=12)
    ax.set_ylabel("$f(x)$", fontsize=12)
    
    ax.axhline(0, color='black', linewidth=1)
    ax.grid(True, linestyle=':', alpha=0.6)
    
    # Légende
    ax.legend(loc='upper right', frameon=True, facecolor='white', fontsize='medium')
    
    # Ajustement des limites
    ax.set_xlim(a - 0.2, b + 0.2)
    ax.set_ylim(np.min(y_fine) - 0.5, np.max(y_fine) + 0.5)
    
    plt.tight_layout()
    plt.show()

illustrate_simpson_error()
Figure 2: La règle de Simpson est une approximation

Les trois règles

Il y a trois régles de Simpson, chacune visant des intervalles de taille différentes.

  1. La première règle traite d’un nombre impair de points séparateurs (3, 5, 7, etc.). C’est la règle dite « 1/3 ».
  2. La seconde règle traite d’un nombre de points séparateurs d’au moins 4, et augmentant par multiple de 3 (4, 7, 10, 13, etc.). C’est la règle dite « 3/8 ».
  3. La dernière règle en est une de complément, qui vise à ajouter un point additionnel aux règles précédentes. C’est la règle dite « 5/8 ».

Chacune des règles est détaillée ci-dessous.

La règle 1/3

Soit une fonction \(f(x)\) dont on cherche l’intégrale sur un intervalle défini: \[\int_a^b f(x) dx.\]

La règle 1/3 est telle qu’on subdivise le domaine d’intégration à l’aide d’un nombre impairs de points: 3, 5, 7, etc. Ces points doivent être espacés de manière égale \((\Delta x)\). La règle 1/3 emploie alors la séquence de poids d’intégration (\(w\)) suivante:

  1. 3 points: 1, 4, 1
  2. 5 points: 1, 4, 2, 4, 1
  3. 7 points: 1, 4, 2, 4, 2, 4, 1
  4. \(2n+1\) points: 1, 4, 2, 4, 2, … ,4, 1 \(n>0\)

Ces poids servent à pondérer chacune des valeurs que prend la fonction qu’on approxime.

Pour une fonction \(f(x)\) dont on cherche à approximer l’intégrale, la règle de Simpson prend la forme: \[\begin{align} \int_a^b f(x)dx &\approx \frac{\Delta x}{3}\left[\underbrace{f(a)}_{1} +\underbrace{4f(a+\Delta x)}_{4} + \underbrace{2f(a + 2\Delta x)}_{2} + \dots + \underbrace{4f(b - \Delta x)}_{4} +\underbrace{f(b)}_{1}\right] \end{align}\]

On remarque que les poids sont appliqués successivements à chaque valeur des intervalles d’intégration. Suivant le pattern 1, 4, 2, 4 .., 4, 1, chaque valeur est multiplié par le poids. On additionne ensuite chacune des valeurs, puis on multiplie par la largeur des intervalles et on divise par trois.

Application

Cherchons la solution à l’intégrale:
\[\begin{align} \int_0^{10} 10x^2 dx =\frac{10000}{3}\approx 3333.3 \end{align}\]

Si on prend les intervalles \(\Delta x= 1\), on obtient 11 points de subdivision. On peut appliquer la règle 1/3. Les valeurs de \(x\), les valeurs de la fonction \(f(x)\) et les poids associés sont rapportés au Tableau 2.

Tableau 2: Application de la règle 1/3.
\(x\) 0 1 2 3 4 5 6 7 8 9 10
\(f(x)\) 0 10 40 90 160 250 360 490 640 810 1000
\(w\) 1 4 2 4 2 4 2 4 2 4 1
\(wf(x)\) 0 40 80 360 320 1000 720 1960 1280 3240 1000

La somme est exactement de 10000. Comme les intervalles sont de 1, la règle de Simpson nous amène à diviser par trois pour avoir 10000/3. Ici, la règle 1/3 donne la valeur exacte de l’intégrale, car c’est une fonction quadratique. De manière générale, la règle de Simspon ne fournira qu’une approximation raisonnable.

La règle 3/8

La règle 3/8 a le même objectif que la règle 1/3. On cherche à approximer l’intégrale d’une fonction \(f(x)\): \[\int_a^b f(x)dx.\]

La différence substantielle avec la règles précédente est que les points de subdivision démarrent à 4 et doivent être des multiples de 3 (4, 7, 10, 13, etc.):

  1. (4): 1, 3, 3, 1
  2. (7): 1, 3, 3, 2, 3, 3, 1
  3. (10): 1, 3, 3, 2, 3, 3, 2, 3, 3, 1
  4. (\(3n + 4\)), \(n\geq 0\): 1, 3, 3, 2, 3, 3, 2, \(\dots\), 3, 3, 1.

Cette approche est donc utile pour des représentations tabulaires de fonctions qui correspondent à ces valeurs d’intervalles.

Dans ce cas, la formule est: \[\begin{align} \int_a^b f(x)dx &\approx \frac{3\Delta x}{8}\left[f(a) +3f(a+\Delta x) + 3f(a + 2\Delta x) +2f(a + 3\Delta x) \dots + 3f(b - \Delta x) +f(b)\right] \end{align}\] On applique donc le pattern de poids d’intégration 1, 3, 3, 2, … 3, 3, 1 aux valeurs de la fonction. On additionne les valeurs, puis on multiplie par \(3 \Delta x / 8\).

Application

Cherchons une approximation à: \[\begin{align} \int_0^6 e^x dx &= e^6 - 1 \approx 402.43. \end{align}\]

On prend des intervalles \(\Delta x = 2\), pour 4 points de subdivision. Les calculs sont présentés au Tableau 3 ci-dessous.

Tableau 3: Application de la règle 3/8
\(x\) 0 2 4 6
\(f(x)\) 1 7.3891 54.598 403.43
\(w\) 1 3 3 1
\(wf(x)\) 1 22.1672 163.7945 403.4288

En faisant la somme de la dernière colonne et en multipliant par \(2\cdot 3/8\), on trouve 442.79. On note cette fois que l’approximation est moins précise.

La règle 5/8

Certaines subdivisions ne cadrent pas avec les règles 1/3 et 3/8 car le nombre de points est ni un nombre impair, ni un multiple de \(4 + 3n\). Dans ce cas, on peut ajouter un intervalle additionnel à l’aide des trois dernières valeurs de la fonction (\(y_n, y_{n-1}, y_{n-2}\)). Les points \(y_n\) et \(y_{n-1}\) délimitent l’intervalle à ajouter, tandis que le point \(y_{n-2}\) délimite l’intervalle précédent.

La règle de Simpson pour l’aire sous la courbe du dernier intervalle est alors donnée par: \[\begin{align} \frac{\Delta x}{12}\left(5y_n + 8y_{n-1}-y_{n-2}\right). \end{align}\]

Application

On s’intéresse à l’intégrale : \[\begin{align} \int_9^{10} \sqrt{x}dx = \frac{2}{3}10^{3/2}- \frac{2}{3}9^{3/2} \approx 3.0819. \end{align}\]

Son aire peut s’approximer avec les points [8, 9, 10] par le calcul:

10 9 8
\(f(x)\) 3.1623 3 2.8284
\(w\) 5 8 -1
\(wf(x)\) 15.8114 24 -2.8284

En multipliant la somme par 1/12, on obtient \(\approx 3.0819\), soit la valeur de l’intégrale.

Conclusion

Les règles de Simpson sont des outils pratiques d’intégration numérique. Elles sont particulièrement adaptées à des tableaux à intervalles fixes. Parce que ce genre de tableau abonde dans les traités de stabilité, les règles sont populaires dans le domaine maritime.

Dans les prochains texte, nous appliquons quelques exemples à des livrets de stabilité de navires et nous dérivons l’origine de ces formules.