傅里叶变换舍入误差 [英] Fourier transform rounding error

查看:203
本文介绍了傅里叶变换舍入误差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在搞乱傅立叶变换。现在我创建了一个执行DFT的类(不像FFT atm那样做)。这是我使用的实现:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆