2013-10-08 42 views
0

在這個DFT上,我一直在撞牆。它應該打印出:8,0,0,0,0,0,0,0,但是我得到8,然後非常非常小的數字。這些舍入錯誤?有什麼我可以做的嗎?我的Radix2 FFT給出了正確的結果,似乎愚蠢的DFT也無法工作。舍入錯誤在DFT中給出不正確的結果?

我開始用複數,所以我知道有一個很好的缺失,我試圖剝奪它來說明問題。

#include <cstdlib> 
#include <math.h> 
#include <iostream> 
#include <complex> 
#include <cassert> 

#define SIZE 8 
#define M_PI 3.14159265358979323846 

void fft(const double src[], double dst[], const unsigned int n) 
{ 
    for(int i=0; i < SIZE; i++) 
    { 
     const double ph = -(2*M_PI)/n; 
     const int gid = i; 

     double res = 0.0f; 
     for (int k = 0; k < n; k++) { 

      double t = src[k]; 

      const double val = ph * k * gid; 
      double cs = cos(val); 
      double sn = sin(val); 

      res += ((t * cs) - (t * sn)); 
      int a = 1; 
     } 

     dst[i] = res; 
     std::cout << dst[i] << std::endl; 
    } 
} 

int main(void) 
{ 
    double array1[SIZE]; 
    double array2[SIZE]; 

    for(int i=0; i < SIZE; i++){ 
     array1[i] = 1; 
     array2[i] = 0; 
    } 

    fft(array1, array2, SIZE); 

    return 666; 
} 
+0

微小的數字有多小? –

+0

@PaulR大小順序爲1e-16 – molbdnilo

+0

這聽起來很正確 - 小數點後16或17位是雙精度的極限。請注意,你應該真的從使用M_PI而不是滾動你自己的,但我認爲這種情況沒有太大的區別。 –

回答

1

的FFT實際上可以產生更精確的結果比直DFT計算,因爲更少的算術OPS通常允許算術量化誤差積累的機會更少。有一篇關於這個話題的FFTW作者的論文。

由於DFT/FFT處理超越基函數,所以使用任何非符號和有限的計算機數字格式,結果永遠不會(除少數特殊情況或幸運事故外)完全正確。因此,非常接近(在幾個LSB內)到零的值應該簡單地被忽略爲噪聲,或者被認爲與零相同。

+0

是啊現在我在做: int tmp = res * 100; dst [i] = tmp/100.0f; 有沒有更高效的東西?我也有一個基數爲2的FFT,但他們只能在2^N大小的數據集上工作,這對我沒有多大的好處。 – lazy8s

相關問題