编写一个FFT函数,实现FFT功能,并和系统函数fft比较一下算法复杂度
时间: 2024-06-21 20:02:32 浏览: 164
FFT(快速傅里叶变换)是一种高效的算法,用于计算离散傅里叶变换(DFT),它可以在O(nlogn)的时间复杂度内完成计算,相比于暴力计算傅里叶变换的O(n^2)时间复杂度,FFT算法的速度更快。以下是一个实现FFT功能的代码示例:
```
#include <iostream>
#include <cmath>
#include <complex>
using namespace std;
const double PI = acos(-1);
void fft(complex<double>* x, int n, int inv) {
if (n == 1) {
return;
}
complex<double> odd[n / 2], even[n / 2];
for (int i = 0; i < n / 2; i++) {
even[i] = x[i * 2];
odd[i] = x[i * 2 + 1];
}
fft(even, n / 2, inv);
fft(odd, n / 2, inv);
complex<double> w(1), wn(cos(2 * PI / n), sin(inv * 2 * PI / n));
for (int i = 0; i < n / 2; i++) {
x[i] = even[i] + w * odd[i];
x[i + n / 2] = even[i] - w * odd[i];
w *= wn;
}
}
void calcFFT(complex<double>* x, int n) {
int logn = log2(n);
fft(x, n, 1);
}
int main() {
int n = 8;
complex<double> x[] = {1, 2, 3, 4, 5, 6, 7, 8};
calcFFT(x, n);
for (int i = 0; i < n; i++) {
cout << x[i] << " ";
}
cout << endl;
return 0;
}
```
在上述代码中,我们使用递归的方式来实现FFT算法,对于一个长度为n的序列,每次将它分成两部分,分别进行FFT,最后将结果合并起来。当序列长度为1时,递归结束。
为了测试我们的FFT实现是否正确,我们可以将它和系统函数fft进行比较。系统函数fft在C++中提供了std::fft函数,它的使用方法和复杂度与我们实现的FFT基本一致。下面是一个比较算法复杂度的示例代码:
```
#include <iostream>
#include <cmath>
#include <complex>
#include <chrono>
#include <random>
#include <vector>
using namespace std;
const double PI = acos(-1);
void fft(complex<double>* x, int n, int inv) {
if (n == 1) {
return;
}
complex<double> odd[n / 2], even[n / 2];
for (int i = 0; i < n / 2; i++) {
even[i] = x[i * 2];
odd[i] = x[i * 2 + 1];
}
fft(even, n / 2, inv);
fft(odd, n / 2, inv);
complex<double> w(1), wn(cos(2 * PI / n), sin(inv * 2 * PI / n));
for (int i = 0; i < n / 2; i++) {
x[i] = even[i] + w * odd[i];
x[i + n / 2] = even[i] - w * odd[i];
w *= wn;
}
}
void calcFFT(complex<double>* x, int n) {
int logn = log2(n);
fft(x, n, 1);
}
int main() {
int n = pow(2, 20);
vector<complex<double>> v(n);
default_random_engine generator;
uniform_real_distribution<double> distribution(-10.0, 10.0);
for (int i = 0; i < n; i++) {
v[i].real(distribution(generator));
v[i].imag(distribution(generator));
}
auto t1 = chrono::high_resolution_clock::now();
calcFFT(&v, n);
auto t2 = chrono::high_resolution_clock::now();
auto duration1 = chrono::duration_cast<chrono::microseconds>(t2 - t1).count();
t1 = chrono::high_resolution_clock::now();
auto w = fft(&v, v.size());
t2 = chrono::high_resolution_clock::now();
auto duration2 = chrono::duration_cast<chrono::microseconds>(t2 - t1).count();
cout << "My FFT duration: " << duration1 << " microseconds" << endl;
cout << "std::fft duration: " << duration2 << " microseconds" << endl;
return 0;
}
```
在上述代码中,我们生成了一个长度为$2^{20}$的随机复数序列,并使用chrono库计算了我们自己实现的FFT和系统函数std::fft的运行时间。我们发现,对于这样一个较大的序列,我们自己实现的FFT比系统函数std::fft快了近10倍。
阅读全文