TP : implanter la fonction exponentielle (4/5)
Partie 4 : calcul de l’exponentielle avec une précision relative fixée ♣¶
Dans la partie 2, vous avez implanté une fonction expRang qui calcule une approximation
de l’exponentielle en tronquant la somme à un certain rang décidé à l’avance. Cependant
le rang nécessaire pour obtenir une bonne précision dépend du nombre réel pour lequel
on veut calculer . On cherche maintenant à calculer une approximation de
l’exponentielle en fixant la précision et non plus le rang. Pour cela on va écrire une
nouvelle fonction d’approximation de l’exponentielle, dans laquelle le rang auquel on
arrête la somme ne sera pas décidé à l’avance, mais dépendra de l’évolution du calcul
qu’on est en train de faire.
Commencez par copier-coller dans les quatre cellules suivantes vos fonctions puissance
et factorielle de la partie 1 ainsi que egal de la
partie 3:
### BEGIN SOLUTION
def puissance(x, n):
r = 1
for i in range(n):
r *= x
return r
### END SOLUTION### BEGIN SOLUTION
def factorielle(n):
r = 1
for i in range(1, n + 1):
r *= i
return r
### END SOLUTION### BEGIN SOLUTION
def egal(x, y, epsilon):
v = abs(x - y)
return (v < epsilon * abs(x)) and (v < epsilon * abs(y))
### END SOLUTIONImplantez une nouvelle fonction d’approximation de l’exponentielle qui somme les termes jusqu’à ce que le prochain terme à ajouter ne modifie pas la valeur de la somme, selon la précision donnée :
def expPrecision(x, epsilon):
"""Calcul de la fonction exponentielle à precision fixée
* Parametre x : un nombre flottant
* Parametre epsilon un nombre flottant
* Retourne e^x avec précision epsilon
"""
### BEGIN SOLUTION
e1 = 0
e2 = 1
i = 1
while not egal(e1, e2, epsilon):
e1 = e2
e2 += puissance(x, i) / factorielle(i)
i += 1
return e2
### END SOLUTIONepsilon = 0.000000001epsilon = 1e-9Le calcul suivant devrait renvoyer :
expPrecision(1, epsilon)2.7182818282861687Il n’y a pas forcément suffisament de chiffres significatifs affichés pour le vérifier. Faisons à la place un test :
assert abs(expPrecision(1, epsilon) - 2.718281828459) < epsilonNotre test d’arrêt ne garantit en fait pas d’obtenir une précision de epsilon : même si le terme suivant est plus petit que epsilon, l’accumulation de tous les termes suivants pourrait largement dépasser epsilon, comme dans les exemples suivants :
assert abs(expPrecision(3, epsilon) - 20.085536923) < 5 * epsilonassert abs(expPrecision(5, epsilon) - 148.413159102) < 50 * epsilonComparez vos résultats avec la fonction exp de python :
import math
math.exp(5)148.4131591025766math.exp(3)20.085536923187668Bilan de la partie 4¶
Très bien, vous avez implanté le calcul de la fonction exponentielle à précision fixée. Maintenant étudions sa performance en calculant son temps d’exécution :
import time
start = time.time()
expPrecision(10, 0.00000001)
print(time.time() - start)0.00011420249938964844
Dans la partie 5, vous tenterez d’optimiser cette implantation.