2017-06-09 35 views
0

我正在嘗試修復一個我發現的程序,因此它需要的值與它作爲自身測試的值不同。程序應該能夠獲取一系列值,這些值將數學函數表示爲信號,輸出應該是對該信號的快速傅立葉變換。以下是我已經有固定的代碼:無法將複雜的<double>轉換爲雙倍

#include <complex> 
#include <iostream> 
#include <valarray> 

#define fnc(x) (x) 

const double PI = 3.141592653589793238460; 

typedef std::valarray<double> CArray; 

union{ 
    double d; 
    int i; 
}num,i; 


void fft(CArray& x) 
{ 
    const size_t N = x.size(); 
    if (N <= 1) return; 

    // divide 
    CArray even = x[std::slice(0, N/2, 2)]; 
    CArray odd = x[std::slice(1, N/2, 2)]; 

    // conquer 
    fft(even); 
    fft(odd); 

    // combine 
    for (size_t k = 0; k < N/2; ++k) 
    { 
     double t = std::polar(1.0, -2 * PI * k/N) * odd[k]; 
     x[k ] = even[k] + t; 
     x[k+N/2] = even[k] - t; 
    } 
} 
    //Complex f = 1.0/sqrt(N); 
    //for (unsigned int i = 0; i < N; i++) 
    // x[i] *= f; 

int main() 
{ 
    num.d=513; 
    double test[num.i]; 
    for(i.i=1; i.i < num.i;++i.i) 
     test[i.i] = (double)fnc(i.i); 
    CArray data(test, num.d); 

    // forward fft 
    fft(data); 

    std::cout << "fft" << std::endl; 
    for (i.i = 0; i.i < num.i; ++i.i) 
    { 
     std::cout << data[i.i] << std::endl; 
    } 
    return 0; 
} 

當我嘗試編譯TI顯示我在34行的樣帶

error: cannot convert 'std::complex' to 'double' in initialization|

,就標誌着這部分行:

for (size_t k = 0; k < N/2; ++k) 
    { 
     double t = std::polar(1.0, -2 * PI * k/N) * odd[k]; 
     x[k ] = even[k] + t; 
     x[k+N/2] = even[k] - t; 
    } 

pesizaly這一個:

 double t = std::polar(1.0, -2 * PI * k/N) * odd[k]; 

如果有人能告訴我如何解決這個問題,我會非常冷靜。 爲了更好的參考,這是原始代碼,以防萬一任何人可以告訴我一個更好的方法來解決它,所以它會記住我想要的。

#include <complex> 
#include <iostream> 
#include <valarray> 
  
const double PI = 3.141592653589793238460; 
  
typedef std::complex<double> Complex; 
typedef std::valarray<Complex> CArray; 
  
// Cooley–Tukey FFT (in-place, divide-and-conquer) 
// Higher memory requirements and redundancy although more intuitive 
void fft(CArray& x) 
{ 
    const size_t N = x.size(); 
    if (N <= 1) return; 
  
    // divide 
    CArray even = x[std::slice(0, N/2, 2)]; 
    CArray odd = x[std::slice(1, N/2, 2)]; 
  
    // conquer 
    fft(even); 
    fft(odd); 
  
    // combine 
    for (size_t k = 0; k < N/2; ++k) 
    { 
     Complex t = std::polar(1.0, -2 * PI * k/N) * odd[k]; 
     x[k ] = even[k] + t; 
     x[k+N/2] = even[k] - t; 
    } 
} 
  
// Cooley-Tukey FFT (in-place, breadth-first, decimation-in-frequency) 
// Better optimized but less intuitive 
// !!! Warning : in some cases this code make result different from not  optimased version above (need to fix bug) 
// The bug is now fixed @2017/05/30 
void fft(CArray &x) 
{ 
    // DFT 
    unsigned int N = x.size(), k = N, n; 
    double thetaT = 3.14159265358979323846264338328L/N; 
    Complex phiT = Complex(cos(thetaT), -sin(thetaT)), T; 
    while (k > 1) 
    { 
     n = k; 
     k >>= 1; 
     phiT = phiT * phiT; 
     T = 1.0L; 
     for (unsigned int l = 0; l < k; l++) 
     { 
      for (unsigned int a = l; a < N; a += n) 
      { 
       unsigned int b = a + k; 
       Complex t = x[a] - x[b]; 
       x[a] += x[b]; 
       x[b] = t * T; 
      } 
      T *= phiT; 
     } 
    } 
    // Decimate 
    unsigned int m = (unsigned int)log2(N); 
    for (unsigned int a = 0; a < N; a++) 
    { 
     unsigned int b = a; 
     // Reverse bits 
     b = (((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1)); 
     b = (((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2)); 
     b = (((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4)); 
     b = (((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8)); 
     b = ((b >> 16) | (b << 16)) >> (32 - m); 
     if (b > a) 
     { 
      Complex t = x[a]; 
      x[a] = x[b]; 
      x[b] = t; 
     } 
    } 
    //// Normalize (This section make it not working correctly) 
    //Complex f = 1.0/sqrt(N); 
    //for (unsigned int i = 0; i < N; i++) 
    // x[i] *= f; 
} 
  
// inverse fft (in-place) 
void ifft(CArray& x) 
{ 
    // conjugate the complex numbers 
    x = x.apply(std::conj); 
  
    // forward fft 
    fft(x); 
  
    // conjugate the complex numbers again 
    x = x.apply(std::conj); 
  
    // scale the numbers 
    x /= x.size(); 
} 
  
int main() 
{ 
    const Complex test[] = { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 }; 
    CArray data(test, 8); 
  
    // forward fft 
    fft(data); 
  
    std::cout << "fft" << std::endl; 
    for (int i = 0; i < 8; ++i) 
    { 
     std::cout << data[i] << std::endl; 
    } 
  
    // inverse fft 
    ifft(data); 
  
    std::cout << std::endl << "ifft" << std::endl; 
    for (int i = 0; i < 8; ++i) 
    { 
     std::cout << data[i] << std::endl; 
    } 
    return 0; 
} 

Ps。如果有人知道我需要的更好的代碼,我也可以使用它。

+1

使用['M_PI'在math.h中](HTTPS://計算器.com/q/1727881/995714)而不是定義你自己的 –

回答

0

錯誤消息非常明確:std::polar返回std::complex,而不是double。看其餘的代碼,也許只是改變t的類型?

1

std::complex<double>double是不兼容的類型。

更改此:

double t = std::polar(1.0, -2 * PI * k/N) * odd[k]; 

這樣:

std::complex<double> t = std::polar(1.0, -2 * PI * k/N) * odd[k]; 

因爲std::polar回報:

The complex cartesian equivalent to the polar format formed by rho and theta.

+0

謝謝,它真的有用,但現在它顯示了一個新的錯誤e後面跟着兩行:'錯誤:無法將'std :: complex '轉換爲賦值|中的'double'。 –

+0

@FelipeTafoyaLoeza,因爲你使用'typedef std :: valarray CArray;',而不是兼容的,例如使用'Complex'而不是'double'。希望有所幫助! =) – gsamaras