傅里叶变换舍入误差 [英] Fourier transform rounding error
问题描述
public static Complex [] Dft(double [] data)
{
int length = data.Length;
Complex [] result = new Complex [length]; (int k = 1; k< = length; k ++)
{
复杂c = Complex.Zero; (int n = 1; n <= length; n ++)
{
c + = Complex.FromPolarCoordinates(data [n-1],(-2 * Math.PI * n * k)/长度);
}
result [k-1] = 1 / Math.Sqrt(length)* c;
}
返回结果;
}
这些是从 Dft {2,3,4})
好吧,这似乎是非常好的,因为这些都是我期待的价值。只有一件事我感到困惑。这一切都与双打的四舍五入有关。
首先,为什么前两个数字不完全相同(0,8660..443 8 )vs(0,8660..443)。为什么它不能计算一个零,你会期望它。我知道2.8E-15是非常接近于零,但不是这样。
任何人都知道这些,边际,错误是如何发生的,如果我可以并且想做一些事情。
似乎没有一个真正的问题,因为它只是一个小错误。但是,如果您比较两个值,那么您如何处理这些舍入误差。
5,2 + 0i! = 5,1961524 + i2.828107 * 10 ^ -15
干杯
我认为你已经向自己解释过 - 精确度有限,精度有限。
如果要清理结果,您可以自己做一些更合理的数字的数字,然后你的零将显示在你想要的地方
要回答您的评论提出的问题,请勿直接尝试比较浮点数 - 使用范围:
if(Math.Abs(float1 - float2)< 0.001){
//他们是一样的!
}
comp.lang.c常见问题有很多问题和答案;关于浮点的答案,您可能有兴趣阅读。
I'm messing around with Fourier transformations. Now I've created a class that does an implementation of the DFT (not doing anything like FFT atm). This is the implementation I've used:
public static Complex[] Dft(double[] data)
{
int length = data.Length;
Complex[] result = new Complex[length];
for (int k = 1; k <= length; k++)
{
Complex c = Complex.Zero;
for (int n = 1; n <= length; n++)
{
c += Complex.FromPolarCoordinates(data[n-1], (-2 * Math.PI * n * k) / length);
}
result[k-1] = 1 / Math.Sqrt(length) * c;
}
return result;
}
And these are the results I get from Dft({2,3,4})
Well it seems pretty okay, since those are the values I expect. There is only one thing I find confusing. And it all has to do with the rounding of doubles.
First of all, why are the first two numbers not exactly the same (0,8660..443 8 ) vs (0,8660..443). And why can't it calculate a zero, where you'd expect it. I know 2.8E-15 is pretty close to zero, but well it's not.
Anyone know how these, marginal, errors occur and if I can and want to do something about it.
It might seem that there's not a real problem, because it's just small errors. However, how do you deal with these rounding errors if you're for example comparing 2 values.
5,2 + 0i != 5,1961524 + i2.828107*10^-15
Cheers
I think you've already explained it to yourself - limited precision means limited precision. End of story.
If you want to clean up the results, you can do some rounding of your own to a more reasonable number of siginificant digits - then your zeros will show up where you want them.
To answer the question raised by your comment, don't try to compare floating point numbers directly - use a range:
if (Math.Abs(float1 - float2) < 0.001) {
// they're the same!
}
The comp.lang.c FAQ has a lot of questions & answers about floating point, which you might be interested in reading.
这篇关于傅里叶变换舍入误差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!