在 C++ 中使用 getline 从文件中获取包含(整数)并将它们输入到数组中以用作 C++ fft 程序的输入

Using getline in C++ to get the contain (integers) from a file and input them into array to be used as input of a C++ fft program

我正在使用 getline 从我的计算机的文件 (myfile.txt) 获取输入,该文件包含以下值:1 1 1 1 0 0 0 0。 这些值中的每一个都将被放入一个数组 x[n] 中,稍后将用作我的快速傅立叶变换程序的输入。 然而,当我是 运行 程序时,输出与原始程序有点不同,即。数组具有直接在程序内部声明的值的那个( const Complex test[] = { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 };)

    //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

顺序

您修改后的代码中有(至少)三点需要更正。

(1) 您在应该使用 8 的地方(如果我没记错的话)使用 16x应该是new double[8](或者double x[8]?为什么要用动态数组?); test应该是Complex test[8];CArray data(test, 16);应该是CArray data(test, 8);

(2) 你没有在读取文件循环中初始化i;所以当你写

x[i]=(double)Result;

i 的值未定义。因此,如果 i 在 [0,16[] 范围内,您将丢失前 7 个值,而第 8 个值在 x[i] 内; x 的其他值未定义。如果 i 超出范围 [0,16[,程序可能会崩溃。

恩路人:x[i]Resultdouble;所以演员阵容是多余的。

我想你的周期应该是(记住你只有 8 个值)类似于

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

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

     x[i]=Result;
   }

(3) 我不明白应该是什么

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

我想你的意图是

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

---- 编辑 ----

更正:加载文件的正确方法可以是

//   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";

对不起。