正弦函数中的 Matlab Bug?
Matlab Bug in Sine function?
有人试过在 MATLAB 中绘制大值的正弦函数吗?
例如:
x = 0:1000:100000;
plot(x,sin(2*pi*x))
我只是想知道为什么这个周期函数的振幅会发生变化?按照我的预期,对于 x
的任何值,该函数的周期为 2*pi
。为什么不是呢?
有人知道吗?有没有办法让它正确?另外,这是一个错误吗?它是已知的吗?
实际上不是振幅变化。这是由于浮点运算的数值不精确。请记住,您指定的整数序列从 0 到 100000,步长为 1000。如果您回忆起三角学,sin(n*x*pi) = 0
当 x
和 n
是整数时,因此理论上您应该获得全零的输出。在您的例子中,n = 2
和 x
是一个从 0 到 100000 的数字,是 1000 的倍数。
但是,这是我在您的 post 中使用上述代码时得到的结果:
看看该图的比例。是 10^{-11}
。你知道它有多小吗?作为进一步的证据,以下是该序列的最大值和最小值:
>> min(sin(2*pi*x))
ans =
-7.8397e-11
>> max(sin(2*pi*x))
ans =
2.9190e-11
这些值太小了,还不如为零呢。您在图中看到的是由于数值不精确造成的。正如我之前提到的,当 n
和 x
是整数时,sin(n*x*pi) = 0
是整数,假设我们有 所有小数位 pi
可用。但是,因为我们总共只有 64 位来表示 pi
,所以您肯定不会得到 正好 零的结果。此外,请注意 sin
函数很可能使用数值近似算法(例如 Taylor / MacLaurin series),因此这也可能导致结果可能不完全为 0。
当然有变通办法,例如使用符号数学工具箱(请参阅 )。在这种情况下,您将得到零,但我不会在这里重点讨论。您的 post 质疑 MATLAB 中适用于数字类型输入的 sin
函数的准确性。理论上,您输入 sin
,因为它是一个整数序列,x
的每个值都应该使 sin(n*x*pi) = 0
。
顺便说一句,这篇文章很好读。这是每个程序员都需要了解的有关浮点运算和函数的知识:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html. A more simple overview can be found here: http://floating-point-gui.de/
因为 pi
的确切值是多少?
这种明显的错误是由于浮点精度的限制。如果你真的need/want绕过你可以用matlab做符号计算,看看两者之间的区别:
>> sin(2*pi*10)
ans =
-2.4493e-15
和
>> sin(sym(2*pi*10))
ans =
0
有人试过在 MATLAB 中绘制大值的正弦函数吗?
例如:
x = 0:1000:100000;
plot(x,sin(2*pi*x))
我只是想知道为什么这个周期函数的振幅会发生变化?按照我的预期,对于 x
的任何值,该函数的周期为 2*pi
。为什么不是呢?
有人知道吗?有没有办法让它正确?另外,这是一个错误吗?它是已知的吗?
实际上不是振幅变化。这是由于浮点运算的数值不精确。请记住,您指定的整数序列从 0 到 100000,步长为 1000。如果您回忆起三角学,sin(n*x*pi) = 0
当 x
和 n
是整数时,因此理论上您应该获得全零的输出。在您的例子中,n = 2
和 x
是一个从 0 到 100000 的数字,是 1000 的倍数。
但是,这是我在您的 post 中使用上述代码时得到的结果:
看看该图的比例。是 10^{-11}
。你知道它有多小吗?作为进一步的证据,以下是该序列的最大值和最小值:
>> min(sin(2*pi*x))
ans =
-7.8397e-11
>> max(sin(2*pi*x))
ans =
2.9190e-11
这些值太小了,还不如为零呢。您在图中看到的是由于数值不精确造成的。正如我之前提到的,当 n
和 x
是整数时,sin(n*x*pi) = 0
是整数,假设我们有 所有小数位 pi
可用。但是,因为我们总共只有 64 位来表示 pi
,所以您肯定不会得到 正好 零的结果。此外,请注意 sin
函数很可能使用数值近似算法(例如 Taylor / MacLaurin series),因此这也可能导致结果可能不完全为 0。
当然有变通办法,例如使用符号数学工具箱(请参阅 sin
函数的准确性。理论上,您输入 sin
,因为它是一个整数序列,x
的每个值都应该使 sin(n*x*pi) = 0
。
顺便说一句,这篇文章很好读。这是每个程序员都需要了解的有关浮点运算和函数的知识:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html. A more simple overview can be found here: http://floating-point-gui.de/
因为 pi
的确切值是多少?
这种明显的错误是由于浮点精度的限制。如果你真的need/want绕过你可以用matlab做符号计算,看看两者之间的区别:
>> sin(2*pi*10)
ans =
-2.4493e-15
和
>> sin(sym(2*pi*10))
ans =
0