Fast Fourier Transform: The first element is correct, but the rest are not

时间:2017-04-08 22:32:16

标签: c++ fft

I'm implementing FFT, and my solution can consistently solve the first element of the transform, but can't do the rest.

Here is the code:

vector<complex<double>> FFT(vector<complex<double>> a, complex<double> w)
{
    if (a.size() == 1) {
        return a;
    }
    vector<complex<double>> even;
    vector<complex<double>> odd;
    for (int i = 0; i < a.size(); i ++) {
        if (i % 2 == 0) {
            even.push_back(a[i]);
        }
        else {
             odd.push_back(a[i]);
        }
    }
    vector<complex<double>> FFTeven = FFT(even, nthRoot(a.size() / 2));
    vector<complex<double>> FFTodd = FFT(odd, nthRoot(a.size() / 2));

    vector<complex<double>> ret;
    for (int i = 0; i < a.size(); i++) {
    ret.push_back(0);
    }
    for (int i = 0; i <= (a.size() / 2) - 1; i++) {
        ret[i] = FFTeven[i] + pow(w, i) * FFTodd[i];
        ret[i + a.size() / 2] = FFTeven[i] - pow(w, i) * FFTodd[i];
    }
    return ret;
}

main code:

int n = 4;
vector <complex<double>> a;
vector<complex<double>> b;
for (int i = 1; i < 9; i++) {
    if (i < 5) {
        a.push_back((complex<double>) i);
    }
    else {
        b.push_back((complex<double>) i);
    }
}
for (int i = 0; i < n; i++) {
    a.push_back(0);
    b.push_back(0);
}
complex<double> w = nthRoot(a.size());

a = FFT(a, w);
b = FFT(b, w);
for (int i = 0; i < a.size() - 1; i++) {
    cout << a[i].real() << ", ";
}
cout << a.back().real() << ">\n";
for (int i = 0; i < b.size() - 1; i++) {
    cout << b[i].real() << ", ";
}
cout << b.back().real() << ">\n";

nthRoot:

complex<double> nthRoot(int n)
{
    return (cos(2 * M_PI / n) + i * sin(2 * M_PI / n));
}

i globally declared:

const complex<double> i = (0.0, 1.0);

example input:

a = <5, 6, 7, 8, 0, 0, 0, 0>

example output:

ret = <26, 31.799, -6, -7.65685, -2, -7.79899, 2, 3.65685>

expected output:

ret = <26, 3.5858, -2, 6.4142, -2, 6.4142, -2, 3.5858>

This FFT is being used to find a convolution, hence the padded zeros at the end of the input vector. Any help would be appeciated.

1 个答案:

答案 0 :(得分:0)

我通过运行代码获得了预期的输出。唯一的区别是当我pushback 0时,我必须使用push_back(complex<double>(0))。我认为不重要。

您是否搞砸了预期的结果和示例结果?

如果有人对此FFT示例感兴趣,我将下面的“复制 - 粘贴 - 运行”版本放在:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <complex>

using namespace std;

complex<double> nthRoot(int n)
{
    return complex<double>(cos(2 * M_PI / n), sin(2 * M_PI / n));
}

vector<complex<double> > FFT(vector<complex<double> > a, complex<double> w)
{
    if (a.size() == 1) {
        return a;
    }
    vector<complex<double> > even;
    vector<complex<double> > odd;
    for (int i = 0; i < a.size(); i ++) {
        if (i % 2 == 0) {
            even.push_back(a[i]);
        }
        else {
             odd.push_back(a[i]);
        }
    }
    vector<complex<double> > FFTeven = FFT(even, nthRoot(a.size() / 2));
    vector<complex<double> > FFTodd = FFT(odd, nthRoot(a.size() / 2));

    vector<complex<double> > ret;
    for (size_t i = 0; i < a.size(); i++) {
        ret.push_back(complex<double>(0));
    }
    for (size_t i = 0; i <= (a.size() / 2) - 1; i++) {
        ret[i] = FFTeven[i] + pow(w, i) * FFTodd[i];
        ret[i + a.size() / 2] = FFTeven[i] - pow(w, i) * FFTodd[i];
    }
    return ret;
}

int main(void) {

  int n = 4;
  vector<complex<double> > a;
  vector<complex<double> > b;
  for (int i = 1; i < 9; i++) {
      if (i < 5) {
          a.push_back((complex<double>) i);
      }
      else {
          b.push_back((complex<double>) i);
      }
  }
  for (int i = 0; i < n; i++) {
      a.push_back(complex<double>(0));
      b.push_back(complex<double>(0));
  }
  complex<double> w = nthRoot(a.size());

  a = FFT(a, w);
  b = FFT(b, w);
  for (int i = 0; i < a.size() - 1; i++) {
      cout << a[i].real() << ", ";
  }
  cout << a.back().real() << ">\n";
  for (int i = 0; i < b.size() - 1; i++) {
      cout << b[i].real() << ", ";
  }
  cout << b.back().real() << ">\n";
}

输出

  

10,-0.414214,-2,2.41421,-2,2.41421,-2,-0.414214&gt;

     

26,3.58579,-2,6.41421,-2,6.41421,-2,3.58579&gt;