本文的IFFT算法是在FFT基础上改变的,之前的FFT算法链接:https://blog.csdn.net/great978/article/details/84033080
这里给出离散傅里叶变换以及逆变换的公式:
具体算法和FFT几乎一致,同样是分开奇偶项,一直到最后两项,然后递归求和,以加法运算代替乘幂运算,和FFT算法不同在于
- 最后的复数需要求一个1/N,这需要我们额外定义一个复数乘以常数的乘法方法;
- 对于根值root,这里面需要求一个共轭(即倒数)
下面给出具体C语言代码:
// IFFT.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#define _CRT_SECURE_NO_WARNINGS
#include "stdlib.h"
#include "math.h"
#include "stdio.h"
#define K 3
#define Pi 3.1415927 //定义圆周率Pi
#define LEN sizeof(struct Compx) //定义复数结构体大小
//-----定义复数结构体-----------------------
struct Compx
{
double real;
double imag;
}Compx;
//-----复数乘法运算函数---------------------
struct Compx mult(struct Compx b1, struct Compx b2)
{
struct Compx b3;
b3.real = b1.real*b2.real - b1.imag*b2.imag;
b3.imag = b1.real*b2.imag + b1.imag*b2.real;
return(b3);
}
struct Compx mult1(struct Compx p, double q)
{
struct Compx r;
r.real = p.real*q;
r.imag = p.imag*q;
return(r);
}
//-----复数加法运算函数---------------------
struct Compx add(struct Compx a, struct Compx b)
{
struct Compx c;
c.real = a.real + b.real;
c.imag = a.imag + b.imag;
return(c);
}
struct Compx IFFT(struct Compx *t, int n, struct Compx root, struct Compx result);
int main()
{
int N, i;
N = 8;
double average = 1 / (double)N;
int x[8];
for (i = 0; i < N; i++)
{
scanf("%d", &x[i]);
}
struct Compx * Source = (struct Compx *)malloc(N*LEN); //为结构体分配存储空间
struct Compx * Result = (struct Compx *)malloc(N*LEN);
struct Compx * Root = (struct Compx *)malloc(N*LEN);
//初始化=======================================
printf("
Source初始化:
");
for (i = 0; i < N; i++)
{
Source[i].real = x[i];
Source[i].imag = 0;
printf("%.4f ", Source[i].real);
printf("+%.4fj ", Source[i].imag);
printf("
");
}
printf("
Result初始化:
");
for (i = 0; i < N; i++)
{
Result[i].real = 0;
Result[i].imag = 0;
printf("%.4f ", Result[i].real);
printf("+%.4fj ", Result[i].imag);
printf("
");
}
printf("
Root初始化:
");
for (i = 0; i < N; i++)
{
Root[i].real = cos(2 * Pi * (2 * i + 1) / (2 * N));
//在IFFT中,需要对根值取共轭,即cos值不变,sin取反
Root[i].imag = -sin(2 * Pi * (2 * i + 1) / (2 * N));
printf("%.4f ", Root[i].real);
printf("+%.4fj ", Root[i].imag);
printf("
");
}
//对结果取平均数,average=1/N,复数乘以常数在一开始定义
for (i = 0; i < N; i++)
{
Result[i] =mult1( IFFT(Source, N, Root[i], Result[i]) , average );
}
//结果表示
printf("
Result计算结果:
");
for (i = 0; i < N; i++)
{
printf("%.4f ", Result[i].real);
printf("+%.4fj ", Result[i].imag);
printf("
");
}
return 0;
}
struct Compx IFFT(struct Compx *t, int n, struct Compx root, struct Compx result)
{
int i, j;
struct Compx * even = (struct Compx *)malloc((n / 2) * LEN);
struct Compx * odd = (struct Compx *)malloc((n / 2) * LEN);
//划分奇偶项
for (i = 0, j = 0; i < n; i += 2, j++)
{
even[j].real = t[i].real;
even[j].imag = t[i].imag;
}
for (i = 1, j = 0; i < n; i += 2, j++)
{
odd[j].real = t[i].real;
odd[j].imag = t[i].imag;
}
if (n == 2)
{
struct Compx s = add(even[0], mult(root, odd[0]));
return add(result, s);
}
else
{
return add(IFFT(even, n / 2, mult(root, root), result), mult(root, IFFT(odd, n / 2, mult(root, root), result)));
}
}
欢迎指正!