Máquina Epsilon En Python

Un manual que estoy estudiando actualmente (soy un novato) dice:

“Los números que difieren en menos de epsilon de la máquina son numéricamente iguales”

Con Python, la máquina epsilon para valores flotantes se puede obtener escribiendo

eps = numpy.finfo(float).eps 

Ahora, si compruebo

 1 + eps/10 != 1 

Obtengo Falso.

Pero si lo compruebo

 0.1 + eps/10 != 0.1 

Obtengo la Verdad.

Mi última expresión lógica se convierte en Falso si divido eps por 100. Entonces, ¿cómo funciona la máquina épsilon? La documentación de Python simplemente dice

“El número positivo representable más pequeño, de manera que 1.0 + eps! = 1.0. El tipo de eps es un tipo de punto flotante apropiado”.

Gracias de antemano.

Los números de punto flotante tienen una cierta precisión, con unos pocos decimales en notación científica. Cuanto mayor sea el número, mayor será el dígito menos significativo en esa representación y, por lo tanto, mayor será el “épsilon” que podría contribuir a ese número.

Por lo tanto, el épsilon es relativo al número al que se agrega, que de hecho se encuentra en la documentación que citó: “… tal que 1.0 + eps! = 1.0”. Si el número de “referencia” es más pequeño, por ejemplo, un orden de magnitud, entonces eps también es más pequeño.

Si ese no fuera el caso, no se podría calcular en absoluto con números más pequeños que eps ( 2.2e-16 en mi caso).

En este caso, en realidad no quieres np.finfo . Lo que desea es np.spacing , que calcula la distancia entre la entrada y el siguiente número más grande que se puede representar exactamente.

Esencialmente, np.spacing calcula “eps” para cualquier número dado. Utiliza el tipo de datos del número (los flotadores nativos de Python son flotadores de 64 bits), por lo que un np.float32 o np.float16 dará una respuesta diferente a un flotador de 64 bits.

Por ejemplo:

 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)) 

Cuyos rendimientos:

 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