你做的很好。但是把FFT换成你自己实现的吧,其它的不要变。
时间: 2024-09-11 17:05:58 浏览: 33
FFT与IFFT算法的C程序实现
好的,如果你想要自己实现FFT而不是依赖于FFTW这样的现成库,那我们可以简化一下代码,只保留基本的DFT(离散傅立叶变换)步骤。以下是一个基于Cooley-Tukey算法的基本二维快速傅立叶变换(FFT)的自定义实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 128 // 你可以根据需要修改这个值
// 自己实现的复数结构体
typedef struct {
double real;
double imag;
} Complex;
// 对复数做加法操作
Complex add(Complex a, Complex b) {
return (Complex) {a.real + b.real, a.imag + b.imag};
}
// 对复数做乘法操作
Complex multiply(Complex a, Complex b) {
return (Complex) {
a.real * b.real - a.imag * b.imag,
a.real * b.imag + a.imag * b.real
};
}
// Cooley-Tukey分解为两个较小的DFT
void decimate(Complex* X, int len) {
if (len <= 1) return;
Complex even[N/2], odd[N/2];
for (int i = 0; i < len/2; i++) {
even[i] = add(X[2*i], X[2*i+1]);
odd[i] = multiply(X[2*i], Complex{cos(M_PI*(2*i+1)/(2*len)), sin(M_PI*(2*i+1)/(2*len))});
}
decimate(even, len/2);
decimate(odd, len/2);
for (int k = 0; k < len/2; k++) {
Complex twiddle = multiply(Complex{cos(M_PI*k/(len/2)), sin(M_PI*k/(len/2))}, odd[k]);
X[k] = add(even[k], twiddle);
X[k+N/2] = subtract(even[k], twiddle); // 减去是为了得到负频率分量
}
}
// DFT函数
void dft(Complex* X, int n) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i > j) {
Complex temp = X[i];
X[i] = X[j];
X[j] = temp;
}
}
}
decimate(X, n);
}
// 自定义的Chirp Z变换
void chirpz_transform_custom(ChirpParams *params) {
// 其他部分保持不变
// ...
// 执行DFT
Complex* input_fft = (Complex*) malloc(sizeof(Complex) * params->n_samples);
for (size_t i = 0; i < params->n_samples; ++i) {
input_fft[i].real = params->input[i];
input_fft[i].imag = 0; // 仅对实信号适用
}
dft(input_fft, params->n_samples);
// ...其他部分继续按照之前的逻辑进行Chirp Z变换
// 处理输出
double* output = (double*) malloc(sizeof(double) * params->n_samples);
for (size_t i = 0; i < params->n_samples / 2 + 1; ++i) {
output[i] = input_fft[i].real; // 取出实部作为频率响应
}
// 清理并释放资源
free(input_fft);
free(output);
}
```
这个版本的代码实现了基本的递归分解DFT过程,对于较大的N值,可能会比FFTW库慢很多。在实际项目中,为了效率和准确性,建议还是使用成熟的FFT库。
阅读全文