提问人:Kevin Spaghetti 提问时间:6/11/2023 更新时间:6/11/2023 访问量:59
使用 numpy.sin 时的精度问题
Precision issue when using numpy.sin
问:
我正在尝试使用 numpy 从正弦波开始生成方波。
我遇到了一个问题:
- 使用常量给出的结果不准确
numpy.pi
- 使用常量给了我正确的结果
3.14
为了创建方波,取正弦波的符号,然后使用最大函数将 -1 转换为 0。
N = 15
x = np.arange(1, N)
s = np.maximum(np.sign(np.sin(3.14 * (x - 1))), np.zeros_like(x))
print(s)
>> [0. 1. 0. 1. 0. 1. 0. 1. 0. 1. 0. 1. 0. 1.]
在 numpy 中使用 pi 常量时,可以给出:
N = 15
x = np.arange(1, N)
s = np.maximum(np.sign(np.sin(np.pi * (x - 1))), np.zeros_like(x))
print(s)
>> [0. 1. 0. 1. 0. 1. 0. 1. 0. 1. 0. 1. 0. 0.]
其中序列不是交替的 1 和 0。使用更多元素,您可以观察到两个以上 0 彼此相邻的块。
[0. 1. 0. 1. 0. 1. 0. 1. 0. 1. 0. 1. 0. 0. 0. 1. 0. 0. 0.]
我主要试图理解使用更精确的值如何导致不精确的结果。
答:
1赞
Dave Rove
6/11/2023
#1
一般来说,如果你想找出为什么这样的事情不起作用,那么检查中间结果,原因可能会变得很明显。
>>> np.sin(np.pi * (np.arange(5)))
array([ 0.0000000e+00, 1.2246468e-16, -2.4492936e-16, 3.6739404e-16, -4.8985872e-16])
因此,整数乘以 pi 的正弦为零,上面显示了浮点精度极限处的抖动。它可以是随机的正数或负数。
1赞
Jérôme Richard
6/11/2023
#2
您的计算在数值上不稳定。使用更高的精度并不能解决问题,而只是将其隐藏得更多一点。主要问题是理论上应该始终为 0,但没有浮点函数是完美的,因此存在错误(通常为 1 ULP)。此错误更改结果的符号。这就是你观察到的。此问题与精度无关。下面是计算内容的几何图示:sin(PI * x)
如果您只想要交替的 0-1 值,则可以向函数添加移位(例如)。如果 shift 为 ,则可以使用函数。sin
np.maximum(np.sign(np.sin(np.pi * (x - 1) + np.pi/2)), np.zeros_like(x))
pi/2
cos
评论