不使用New和delete,写一个FFT算法的C语言实现,输入数组是x,输出数组为y,点数为N
时间: 2023-05-26 20:03:32 浏览: 123
C语言实现的FFT算法
以下是使用malloc和free函数实现FFT算法的C语言代码:
```
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define PI 3.14159265358979323846
void FFT(double *x_real, double *x_imag, double *y_real, double *y_imag, int N);
void FFT_helper(double *x_real, double *x_imag, double *y_real, double *y_imag, int N, int skip);
void IFFT(double *x_real, double *x_imag, double *y_real, double *y_imag, int N);
void IFFT_helper(double *x_real, double *x_imag, double *y_real, double *y_imag, int N, int skip);
int main()
{
int N = 8; // 点数
double *x_real, *x_imag, *y_real, *y_imag; // 输入输出数组
// 分配数组内存并初始化
x_real = (double*)malloc(N * sizeof(double));
x_imag = (double*)malloc(N * sizeof(double));
y_real = (double*)malloc(N * sizeof(double));
y_imag = (double*)malloc(N * sizeof(double));
for(int i = 0; i < N; i++)
{
x_real[i] = i + 1; // 初始化实数部分
x_imag[i] = 0; // 初始化虚数部分
y_real[i] = 0; // 初始化实数部分
y_imag[i] = 0; // 初始化虚数部分
}
// 进行FFT
FFT(x_real, x_imag, y_real, y_imag, N);
// 输出结果
printf("FFT结果:\n");
for(int i = 0; i < N; i++)
{
printf("%.2f + %.2fi\n", y_real[i], y_imag[i]);
}
// 进行IFFT
IFFT(y_real, y_imag, x_real, x_imag, N);
// 输出结果
printf("IFFT结果:\n");
for(int i = 0; i < N; i++)
{
printf("%.2f + %.2fi\n", x_real[i] / N, x_imag[i] / N);
}
// 释放数组内存
free(x_real);
free(x_imag);
free(y_real);
free(y_imag);
return 0;
}
void FFT(double *x_real, double *x_imag, double *y_real, double *y_imag, int N)
{
FFT_helper(x_real, x_imag, y_real, y_imag, N, 1);
}
void FFT_helper(double *x_real, double *x_imag, double *y_real, double *y_imag, int N, int skip)
{
if(N == 1) // 如果点数为1,则不需要递归计算
{
y_real[0] = x_real[0];
y_imag[0] = x_imag[0];
}
else
{
int M = N / 2;
FFT_helper(x_real, x_imag, y_real, y_imag, M, skip * 2); // 递归计算下标为偶数的点
FFT_helper(x_real + skip, x_imag + skip, y_real + M, y_imag + M, M, skip * 2); // 递归计算下标为奇数的点
for(int k = 0; k < M; k++)
{
double real_part = y_real[k];
double imag_part = y_imag[k];
double angle = -2 * PI * k / N; // 旋转因子的角度
double cos_angle = cos(angle);
double sin_angle = sin(angle);
double offset_real = cos_angle * y_real[k + M] - sin_angle * y_imag[k + M];
double offset_imag = sin_angle * y_real[k + M] + cos_angle * y_imag[k + M];
// 两个复数相加
y_real[k] = real_part + offset_real;
y_imag[k] = imag_part + offset_imag;
y_real[k + M] = real_part - offset_real;
y_imag[k + M] = imag_part - offset_imag;
}
}
}
void IFFT(double *x_real, double *x_imag, double *y_real, double *y_imag, int N)
{
IFFT_helper(x_real, x_imag, y_real, y_imag, N, 1);
for(int i = 0; i < N; i++) // IFFT计算完成后,需要将实部和虚部除以N
{
y_real[i] = y_real[i] / N;
y_imag[i] = y_imag[i] / N;
}
}
void IFFT_helper(double *x_real, double *x_imag, double *y_real, double *y_imag, int N, int skip)
{
if(N == 1) // 如果点数为1,则不需要递归计算
{
y_real[0] = x_real[0];
y_imag[0] = x_imag[0];
}
else
{
int M = N / 2;
IFFT_helper(x_real, x_imag, y_real, y_imag, M, skip * 2); // 递归计算下标为偶数的点
IFFT_helper(x_real + skip, x_imag + skip, y_real + M, y_imag + M, M, skip * 2); // 递归计算下标为奇数的点
for(int k = 0; k < M; k++)
{
double real_part = y_real[k];
double imag_part = y_imag[k];
double angle = 2 * PI * k / N; // 旋转因子的角度
double cos_angle = cos(angle);
double sin_angle = sin(angle);
double offset_real = cos_angle * y_real[k + M] - sin_angle * y_imag[k + M];
double offset_imag = sin_angle * y_real[k + M] + cos_angle * y_imag[k + M];
// 两个复数相加并除以2
y_real[k] = (real_part + offset_real) / 2;
y_imag[k] = (imag_part + offset_imag) / 2;
y_real[k + M] = (real_part - offset_real) / 2;
y_imag[k + M] = (imag_part - offset_imag) / 2;
}
}
}
```
注:在使用完malloc分配的内存后,需要使用free函数释放对应的内存,避免内存泄漏。
阅读全文