2017-06-09 26 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行目にNECT

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この1:

 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:// stackoverflowの.com/q/1727881/995714)の代わりに –

答えて

0

エラーメッセージはかなり明白です:std::polardoubleではなくstd::complexを返します。コードの残りの部分を見ると、おそらく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

という名前を付けてくれてありがとうございました。それは実際に働いていましたが、 'エラー:std :: complex 'を代入で' double'に変換することはできません。 –

+0

@FelipeTafoyaLezaあなたが 'typedef std :: valarray CArray;'を使用していて、互換性のあるものではないので、たとえば 'double'の代わりに' Complex'を使用しているからです。希望が助けてくれる! =) – gsamaras

関連する問題