我尝试用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.]
我主要是想了解使用更精确的值如何导致不精确的结果。
2条答案
按热度按时间rm5edbpk1#
你的计算数值不稳定。使用更高的精度不会解决问题,而只是将其隐藏得更深一点。主要问题是
sin(PI * x)
理论上应该总是0,但是没有 * 浮点 * 函数是完美的,所以会有错误(通常是1 ULP)。此错误会更改结果的符号。这就是你所观察到的。这个问题与精度无关。下面是你计算的几何图:如果你只是想要交替的0-1值,你可以添加一个移位到
sin
函数(例如:np.maximum(np.sign(np.sin(np.pi * (x - 1) + np.pi/2)), np.zeros_like(x))
)。如果移位为pi/2
,则可以使用cos
函数。dnph8jn42#
一般来说,如果你想找到为什么这样的东西不工作,然后检查中间结果,原因可能会变得明显。
因此,整数乘以pi的sin为零,上图显示了浮点数精度极限时的抖动。它可以是随机的正或负。