import numpy as np #pour disposer des tableaux de type array
import matplotlib.pyplot as plt #pour les graphiques
% matplotlib inline
#pour l'affichage des graphiques dans la page et non pas dans une fenetre pop up
import operator #pour utiliser les opérateurs de base sous forme de fonctions
from sympy import * #pour le calcul formel
init_printing()
t = symbols('t')
def dérivée(exp, t):
return diff(exp,t)
def simplifier(exp):
return simplify(exp)
Soit $f$ la fonction définie sur $\mathbb{R}$ par $f(x)=(6-x)\sqrt{x}$ definie sur $[0;6]$ et dérivable sur $]0;6]$.
$f$ est dérivable sur $]0;6]$ comme produit de fonctions dérivables sur $]0;6]$ mais elle n'est pas dérivable en $0$.
#expression de f(x)
fexp = (6 - t)*sqrt(t)
fexp
#expression de f'(x)
fprimexp = dérivée(fexp, t)
fprimexp
simplifier(fprimexp)
f = lambdify(t, fexp,"numpy")
fprim = lambdify(t, fprimexp,"numpy")
#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 = 0, 6, -6 , 6
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')
D'après un corollaire du théorème des valeurs intermédiaires, l'équation $f(x)=4$ possède donc une unique solution $\alpha$ dans l'intervalle $[0;2]$
D'après un corollaire du théorème des valeurs intermédiaires, l'équation $f(x)=4$ possède donc une unique solution $\beta$ dans l'intervalle $[2,6]$. De plus cette solution est $4$ car $f(4)=4$.
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
balayage(f, 0, 2, 0.2, 4)
balayage(f, 0.4, 0.6, 0.02, 4)
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'))
dicho_tab(f, 0, 1, 0.02, 4)
dicho(f, 0, 1, 0.02, 4)
dicho_tab(f, 0, 1, 0.002, 4)
dicho(f, 0, 1, 0.02, 4)
n = 0
while 1/2**n > 0.002:
n += 1
print(n)
L'intervalle de départ a pour amplitude 1 ($a_0=0$ et $b_0=1$) A chaque étape l'amplitude de l'intervalle de recherche est divisée par 2 Au bout de $n$ étapes, l'amplitude de la zone de recherche est de $\frac{b_{0}-a_{0}}{2^n}$ soit $\frac{1}{2^n}$ ici. Avec la calculatrice (voir ci-dessus ou le logarithme népérien) on peut vérifier que le plus petit entier $n$ tel que $\frac{1}{2^n} \leqslant 0,002$ est $n=9$