que - ¿Por qué el pecado(180) no es cero cuando se usa python y numpy?
python lenguaje (2)
El número π
no se puede representar exactamente como un número de coma flotante. Entonces, np.radians(180)
no te da π
, te da 3.1415926535897931
.
Y sin(3.1415926535897931)
es de hecho algo así como 1.22e-16
.
Entonces, ¿cómo lidias con esto?
Tienes que calcular, o al menos adivinar, los límites de error absolutos y / o relativos apropiados, y luego en lugar de x == y
, escribes:
abs(y - x) < abs_bounds and abs(y-x) < rel_bounds * y
(Esto también significa que tiene que organizar su computación para que el error relativo sea mayor en relación a y
que a x
. En su caso, porque y
es la constante 0
, eso es trivial, simplemente hágalo hacia atrás).
Numpy proporciona una función que hace esto por usted en una matriz completa, allclose
:
np.allclose(x, y, rel_bounds, abs_bounds)
(Esto realmente comprueba abs(y - x) < abs_ bounds + rel_bounds * y)
, pero eso casi siempre es suficiente, y puedes reorganizar tu código fácilmente cuando no lo es).
En tu caso:
np.allclose(0, np.sin(np.radians(180)), rel_bounds, abs_bounds)
Entonces, ¿cómo sabes cuáles son los límites correctos? No hay forma de enseñarle suficiente análisis de errores en una respuesta SO. La propagación de la incertidumbre en Wikipedia ofrece una visión general de alto nivel. Si realmente no tiene ni idea, puede usar los valores predeterminados, que son 1e-5
relativos y 1e-8
absoluto.
¿Alguien sabe por qué el siguiente no es igual a 0?
import numpy as np
np.sin(np.radians(180))
o:
np.sin(np.pi)
Cuando lo ingreso en python me da 1.22e-16.
El problema no es un error de redondeo de pi. Tenga en cuenta que el problema no aparece para el coseno:
In [2]: np.sin(np.pi)
Out[2]: 1.2246467991473532e-16 != 0.
In [3]: np.cos(np.pi)
Out[3]: -1.0 == -1.
El problema es mucho más ... complicado. Está relacionado con la precisión de pi dentro del procesador. Esto fue descubierto y explicado aquí: https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion/