Import des bibliothèques Python

In [1]:
import numpy as np                #pour disposer des tableaux de type array
import matplotlib.pyplot as plt   #pour les graphiques
In [2]:
% matplotlib inline
#pour l'affichage des graphiques dans la page et non pas dans une fenetre pop up
In [3]:
import operator                   #pour utiliser les opérateurs de base sous forme de fonctions
In [4]:
from sympy import *               #pour le calcul formel
init_printing()
t = symbols('t')
In [5]:
def dérivée(exp, t):
    return diff(exp,t)

def simplifier(exp):
    return simplify(exp)

Résolution approchée de $g(x)=0$ par dichotomie, exo 8 de la fiche

Soit $f$ la fonction définie sur$[-5;-1]$ par $g(x)=2x^3+3x^2+2$ definie sur $[-5;-1]$ et dérivable sur $[-5;-1]$.

Question 1 : Calcul de dérivée

In [6]:
#expression de f(x)
fexp = 2*t**3 + 3*t**2 + 2
fexp
Out[6]:
$$2 t^{3} + 3 t^{2} + 2$$
In [7]:
#expression de f'(x)
fprimexp = dérivée(fexp, t)
fprimexp
Out[7]:
$$6 t^{2} + 6 t$$
In [8]:
simplifier(fprimexp)
Out[8]:
$$6 t \left(t + 1\right)$$

Questions 2 et 3 Etude des variations de $f$

In [9]:
f = lambdify(t, fexp,"numpy")
fprim = lambdify(t, fprimexp,"numpy")
In [10]:
#tracé des  courbes  de f et f'
#Message d'erreur pour f' pour le point d'abscisse 0 (division par 0)
xmin, xmax, ymin, ymax = -5, -1, -20 , 20
plt.axis([xmin, xmax, ymin, ymax])
tx = np.linspace(xmin, xmax, 1001)
ty = f(tx)
tz = fprim(tx)
plt.axhline(color='blue')
plt.axvline(color='blue')
plt.grid(True)
plt.plot(tx, ty, linestyle='-', linewidth=2, color='red', label=r'$y=f(x)$')
plt.plot(tx, tz, linestyle='-', linewidth=1, color='green', label=r"$y=f'(x)$")
plt.legend(loc='lower right')
         
Out[10]:
<matplotlib.legend.Legend at 0xaf7d656c>

Question 4 Existence de solutions de l'équation $g(x)=0$

  • $g:x \mapsto g(x)=2x^3+3x^2+2$ est dérivable donc continue sur $[-5;-1]$
  • $g(-5)<0$ et $g(-1)>0$
  • $f$ est strictement croissante sur $[-5;-1]$

D'après un corollaire du théorème des valeurs intermédiaires, l'équation $g(x)=0$ possède donc une unique solution $\alpha$ dans l'intervalle $[-5;-1]$

Résolution approchée par balayage

In [12]:
def balayage(g, a, b, pas, k):
    """Retourne un intervalle d'amplitude pas encadrant l'unique solution de g(x)= k
    dans l'intervalle [a,b]"""
    if g(a) < k:
        comparaison = lambda u, v : operator.lt(u,v)
    else:
        comparaison = lambda u, v : operator.gt(u,v)
    x = a
    #en-tete du tableau
    print('|{etape:^16}|{t:^12}|{ft:^12}|'.format(etape='Etape', t='t', ft='g(t)'))
    count = 1
    while comparaison(g(x), k):
        print('|{etape:^16}|{t:^12.6f}|{ft:^12.6f}|'.format(etape=count,t=x, ft=g(x)))
        x += pas
        count += 1
    print('|{etape:^16}|{t:^12.6f}|{ft:^12.6f}|'.format(etape=count,t=x, ft=g(x)))       
    return x - pas, x
In [13]:
balayage(f, -5, -1, 0.1, 0)
|     Etape      |     t      |    g(t)    |
|       1        | -5.000000  |-173.000000 |
|       2        | -4.900000  |-161.268000 |
|       3        | -4.800000  |-150.064000 |
|       4        | -4.700000  |-139.376000 |
|       5        | -4.600000  |-129.192000 |
|       6        | -4.500000  |-119.500000 |
|       7        | -4.400000  |-110.288000 |
|       8        | -4.300000  |-101.544000 |
|       9        | -4.200000  | -93.256000 |
|       10       | -4.100000  | -85.412000 |
|       11       | -4.000000  | -78.000000 |
|       12       | -3.900000  | -71.008000 |
|       13       | -3.800000  | -64.424000 |
|       14       | -3.700000  | -58.236000 |
|       15       | -3.600000  | -52.432000 |
|       16       | -3.500000  | -47.000000 |
|       17       | -3.400000  | -41.928000 |
|       18       | -3.300000  | -37.204000 |
|       19       | -3.200000  | -32.816000 |
|       20       | -3.100000  | -28.752000 |
|       21       | -3.000000  | -25.000000 |
|       22       | -2.900000  | -21.548000 |
|       23       | -2.800000  | -18.384000 |
|       24       | -2.700000  | -15.496000 |
|       25       | -2.600000  | -12.872000 |
|       26       | -2.500000  | -10.500000 |
|       27       | -2.400000  | -8.368000  |
|       28       | -2.300000  | -6.464000  |
|       29       | -2.200000  | -4.776000  |
|       30       | -2.100000  | -3.292000  |
|       31       | -2.000000  | -2.000000  |
|       32       | -1.900000  | -0.888000  |
|       33       | -1.800000  |  0.056000  |
Out[13]:
$$\left ( -1.9000000000000017, \quad -1.8000000000000016\right )$$
In [14]:
balayage(f, -1.9, -1.8, 0.01, 0)
|     Etape      |     t      |    g(t)    |
|       1        | -1.900000  | -0.888000  |
|       2        | -1.890000  | -0.786238  |
|       3        | -1.880000  | -0.686144  |
|       4        | -1.870000  | -0.587706  |
|       5        | -1.860000  | -0.490912  |
|       6        | -1.850000  | -0.395750  |
|       7        | -1.840000  | -0.302208  |
|       8        | -1.830000  | -0.210274  |
|       9        | -1.820000  | -0.119936  |
|       10       | -1.810000  | -0.031182  |
|       11       | -1.800000  |  0.056000  |
Out[14]:
$$\left ( -1.8099999999999998, \quad -1.7999999999999998\right )$$
In [15]:
balayage(f, -1.81, -1.8, 0.001, 0)
|     Etape      |     t      |    g(t)    |
|       1        | -1.810000  | -0.031182  |
|       2        | -1.809000  | -0.022393  |
|       3        | -1.808000  | -0.013620  |
|       4        | -1.807000  | -0.004863  |
|       5        | -1.806000  |  0.003879  |
Out[15]:
$$\left ( -1.8070000000000004, \quad -1.8060000000000005\right )$$

Résolution approchée par dichotomie

Fonctions Python

In [16]:
def dicho(f,a,b,e, k):
    """valeur approchée à e près de la solution de f(x)=k
    sur [a,b]. On admet que l'utilisateur saisit des paramètres
    où la dichotomie peut s'appliquer. Construit une figure 
    à chaque étape.
    Les valeurs de a et b affichées sont celles en sortie de boucle."""
    etape = 0 #nombre d'étapes
    if f(a) <= f(b):
        #croissant ou du moins passage de - à +
        croissant = True
    else:
        croissant = False
    while b - a > e:
        etape += 1
        #on calcule le milieu du segment [a,b]
        m = (a+b)/2
        #figure
        x = np.linspace(a,b,500)
        y = f(x)
        plt.xlim(a,b)
        if croissant:
            plt.ylim(max(f(a),-50),min(f(b),50))
        else:
            plt.ylim(max(f(b),-50),min(f(a),50))
        plt.plot(x,y,color='red')
        plt.grid(True)
        plt.axhline(k)
        plt.title('a=%.4f et m=%.4f et b=%.4f'%(a,m,b))
        plt.show()
        #fin de la figure
        s = (f(m) - k)*(f(a) - k)
        #si f(m) - k  et f(a) - k sont de meme signe, f(x)=k dans ]m,b[
        if s > 0:
            a = m
        #si f(m) - k  et f(a) - k sont de signes opposés, f(x)=k dans ]a,m]
        else:
            b = m       
    return a, b, etape

def dicho_tab(f,a,b,e, k):
    """valeur approchée à e près de la solution de f(x)=k
    sur [a,b]. On admet que l'utilisateur saisit des paramètres
    où la dichotomie peut s'appliquer. 
    Ne retourne rien mais remplit un tableau avec les valeurs
    de a, b et m aux differentes etapes.
    Les valeurs de a et b affichées sont celles en sortie de boucle"""
    count = 0 #nombre d'étapes
    if f(a) <= f(b):
        #croissant ou du moins passage de - à +
        croissant = True
    else:
        croissant = False
    #en-tete du tableau
    print('|{etape:^16}|{median:^12}|{test:^10}|{binf:^12}|{bsup:^12}|'.format(etape='Etape',
                                                                     binf='a', bsup='b', median='m',
                                                                     test='Choix ?'))
    #première ligne du tableau
    #remplissage de la ligne du tableau
    print('|{etape:^16}|{median:^12}|{test:^10}|{binf:^12}|{bsup:^12}|'.format(etape='initialisation',
                                                                     binf=a, bsup=b, median=str(None),
                                                                     test=str(None)))
    while b - a > e:
        count += 1
        #on calcule le milieu du segment [a,b]
        m = (a+b)/2
        s = (f(m) - k)*(f(a) - k)
        #si f(m) - k  et f(a) - k sont de meme signe, f(x)=k dans ]m,b[
        if s > 0:
            a = m
        #si f(m) - k  et f(a) - k sont de signes opposés, f(x)=k dans ]a,m]
        else:
            b = m
        #remplissage de la ligne du tableau
        print('|{etape:^16}|{median:^12}|{test:^10}|{binf:^12}|{bsup:^12}|'.format(etape=count,
                                                                     binf=a, bsup=b, median=m,
                                                                     test= 'gauche' if b == m else 'droite'))   

Résolution par dichotomie de l'équation $g(x)=0$ dans l'intervalle $[-5;-1]$

D'abord on s'arrete lorsque l'amplitude de l'intervalle $[a,b]$ est inférieure ou égale à $0,01$

In [17]:
dicho_tab(f, -5, -1, 0.01, 0)
|     Etape      |     m      | Choix ?  |     a      |     b      |
| initialisation |    None    |   None   |     -5     |     -1     |
|       1        |    -3.0    |  droite  |    -3.0    |     -1     |
|       2        |    -2.0    |  droite  |    -2.0    |     -1     |
|       3        |    -1.5    |  gauche  |    -2.0    |    -1.5    |
|       4        |   -1.75    |  gauche  |    -2.0    |   -1.75    |
|       5        |   -1.875   |  droite  |   -1.875   |   -1.75    |
|       6        |  -1.8125   |  droite  |  -1.8125   |   -1.75    |
|       7        |  -1.78125  |  gauche  |  -1.8125   |  -1.78125  |
|       8        | -1.796875  |  gauche  |  -1.8125   | -1.796875  |
|       9        | -1.8046875 |  gauche  |  -1.8125   | -1.8046875 |
In [18]:
dicho(f, -5, -1, 0.01, 0)
Out[18]:
$$\left ( -1.8125, \quad -1.8046875, \quad 9\right )$$

Ensuite on s'arrete lorsque l'amplitude de l'intervalle $[a,b]$ est inférieure ou égale à $0,001$

In [20]:
dicho_tab(f, -5, -1, 0.001, 0)
|     Etape      |     m      | Choix ?  |     a      |     b      |
| initialisation |    None    |   None   |     -5     |     -1     |
|       1        |    -3.0    |  droite  |    -3.0    |     -1     |
|       2        |    -2.0    |  droite  |    -2.0    |     -1     |
|       3        |    -1.5    |  gauche  |    -2.0    |    -1.5    |
|       4        |   -1.75    |  gauche  |    -2.0    |   -1.75    |
|       5        |   -1.875   |  droite  |   -1.875   |   -1.75    |
|       6        |  -1.8125   |  droite  |  -1.8125   |   -1.75    |
|       7        |  -1.78125  |  gauche  |  -1.8125   |  -1.78125  |
|       8        | -1.796875  |  gauche  |  -1.8125   | -1.796875  |
|       9        | -1.8046875 |  gauche  |  -1.8125   | -1.8046875 |
|       10       |-1.80859375 |  droite  |-1.80859375 | -1.8046875 |
|       11       |-1.806640625|  droite  |-1.806640625| -1.8046875 |
|       12       |-1.8056640625|  gauche  |-1.806640625|-1.8056640625|
In [21]:
dicho(f, -5, -1, 0.001, 0)
Out[21]:
$$\left ( -1.806640625, \quad -1.8056640625, \quad 12\right )$$