2016-05-22 3 views
-1

getlineを使用してファイル(myfile.txt)からの入力をmy 1 1 1 1 0 0 0 0. これらの各値は、後で高速フーリエ変換プログラムの入力として使用される配列x [n]に入れられます。 しかし、私がプログラムを実行しているとき、出力は元のプログラムと少し異なります。アレイは、プログラム中に直接宣言された値を有するもの(constの複雑なテスト[] = {1.0、1.0、1.0、1.0、0.0、0.0、0.0、0.0};)C++でgetlineを使用してファイルから包含(整数)を取得し、配列に入力してC++ fftプログラムの入力として使用

//original code 
    #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 
    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);`enter code here` 

     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; 
    }` 

//new modified code 
#include <complex> 
#include <iostream> 
#include <valarray> 
#include <malloc.h> 
#include <string> 
#include <stdlib.h> 
#include <fstream> 
#include <cstdio> 
#include <cstdlib> 

using namespace std; 
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 
/* 
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; 
     } 
    } 

} */ 
// 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() 

{ 

    int n=0; 
    int b=0; 
    int q=0; 
    int i; 
    int Nx=0; 
    //double *x; 
     double x [8]; 
    /**************************************************** getting x ********************************************/ 

     string line; 
     double Result; 
      ifstream myfile ("myfile.txt"); 
      if (myfile.is_open()) 
       { 
       for (i = 0 ; (i < 8) && (myfile >> x[i]) ; ++i) 

      cout << line << '\n'; 
       stringstream convert(line); 

       if (!(convert >> Result)) 
       Result = 0; 

       x[i]=Result; 

       } 
      else cout << "Unable to open file"; 
    /****************************************************************************************************************/ 


    Complex test[8];  
    for (i = 0 ; i < 8 ; ++i) 
    test[i] = x[i]; 

    CArray data(test, 8); 

    // forward fft 
    fft(data); 

    std::cout << "fft" << std::endl; 
    for (int i = 0; i < 8; ++i) 
    { 
     cout << data[i] << 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; 
} 



The purpose of this task is to calculate the FFT (Fast Fourier Transform) of an input se 

quence

+0

あなたの質問を明確にするために、コメントの代わりに編集することができます。しかし、もっと重要なことは、サイトのガイドラインを読む時間がかかることです。特に、問題は最小限の完全な例に減らさなかったので、あなたの質問はトピックとはみなされません。 –

答えて

0

修正されたコードには少なくとも3つのポイントがあります。

(1)16を使用します(私が間違っていない場合)8を使用してください。 xnew double[8](またはdouble x[8]?なぜ動的配列を使用しますか)です。 testCArray data(test, 16);があるべき、Complex test[8];あるべきCArray data(test, 8);

(2)あなたは読書ファイルループ内iを初期化しません。あなたが書くときに

x[i]=(double)Result; 

の値は、iの値は未定義です。したがって、iが[0,16 [0]の範囲内にあれば、最初の7つの値が失われ、8番目の値はx[i]になります。 xの他の値は未定義です。 iが[0,16 []の範囲外の場合、プログラムがクラッシュする可能性があります。

En passant:x[i]およびResultは、doubleです。キャストは凄いです。

私はあなたのサイクルは(あなたが唯一の8つの値を持って覚えている)する必要があると仮定(3)私は

const Complex test[16] = x[i]; 

どうあるべきか

for (i = 0 ; (i < 8) && getline(myfile, line) ; ++i) 
    { 
    cout << line << '\n'; 
    stringstream convert(line); 

    if (!(convert >> Result)) 
     Result = 0; 

    x[i]=Result; 
    } 

のようなものを理解していない私はあなたの意図だったと仮定

Complex test[8];  
for (i = 0 ; i < 8 ; ++i) 
    test[i] = x[i]; 

---- EDIT ----

修正:ファイルをロードするための正しい方法は

// double Result; 
ifstream myfile ("myfile.txt"); 
if (myfile.is_open()) 
{ 
    for (i = 0 ; (i < 8) && (myfile >> x[i]) ; ++i 
    ; 

    // no need for myfile.close() (take care of it the destructor) 
} 
else cout << "Unable to open file"; 

申し訳ありませんすることができます。

+0

こんにちはマックス、あなたのお勧めをありがとう、提案したコードを修正しましたが、元のプログラムとはまだ異なります。私は新しいプログラムで置き換えました。 – Serge

+0

@ Serge - それは私のせいです、申し訳ありません:私の答えを修正しました – max66

+0

マックス、それは今動作します!あなたの助けをありがとう、私は正しいコードで私の以前の投稿を再び変更しました。誰かが知っている、誰かが今日私と同じ問題を将来的に持っているかもしれない。 – Serge

関連する問題