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.
答案 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;