Un manuel que j'étudie actuellement (je suis un débutant) dit:
"Les nombres qui diffèrent de moins que la machine epsilon sont numériquement les mêmes"
Avec Python, la machine epsilon pour les valeurs flottantes peut être obtenue en tapant
eps = numpy.finfo(float).eps
Maintenant, si je vérifie
1 + eps/10 != 1
J'obtiens Faux.
Mais si je vérifie
0.1 + eps/10 != 0.1
J'obtiens True.
Ma dernière expression logique devient fausse si je divise eps par 100. Alors, comment fonctionne epsilon machine? La documentation Python dit simplement
"Le plus petit nombre positif représentable tel que 1.0 + eps! = 1.0. Le type de eps est un type à virgule flottante approprié."
Merci d'avance.
Les nombres à virgule flottante ont une certaine précision, à quelques décimales près en notation scientifique. Plus le nombre est grand, plus le chiffre le moins significatif est grand dans cette représentation, et donc plus le "epsilon" qui pourrait contribuer à ce nombre est grand.
Ainsi, l'epsilon est relatif au nombre auquel il est ajouté, ce qui est en fait indiqué dans la documentation que vous avez citée: "... tel que 1.0 + eps! = 1.0". Si le numéro de "référence" est plus petit de, par ex. un ordre de grandeur, puis eps est également plus petit.
Si ce n'était pas le cas, vous ne pouviez pas calculer pas du tout avec des nombres inférieurs à eps (2.2e-16
dans mon cas).
Dans ce cas, vous ne voulez vraiment pas np.finfo
. Ce que vous voulez, c'est np.spacing
, qui calcule la distance entre l'entrée et le prochain plus grand nombre qui peut être représenté exactement.
Essentiellement, np.spacing
calcule "eps" pour un nombre donné. Il utilise le type de données du nombre (natif python flottants sont des flottants 64 bits), donc un np.float32
ou np.float16
donnera une réponse différente de celle d'un flottant 64 bits.
Par exemple:
import numpy as np
print 'Float64, 1.0 -->', np.spacing(1.0)
print 'Float64, 1e12 -->', np.spacing(1e12)
print 'Float64, 1e-12 -->', np.spacing(1e-12)
print ''
print 'Float32, 1.0 -->', np.spacing(np.float32(1.0))
print 'Float32, 1e12 -->', np.spacing(np.float32(1e12))
print 'Float32, 1e-12 -->', np.spacing(np.float32(1e-12))
Ce qui donne:
Float64, 1.0 --> 2.22044604925e-16
Float64, 1e12 --> 0.0001220703125
Float64, 1e-12 --> 2.01948391737e-28
Float32, 1.0 --> 1.19209e-07
Float32, 1e12 --> 65536.0
Float32, 1e-12 --> 1.0842e-19