本文的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("\nSource初始化:\n");
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("\n");
}
printf("\nResult初始化:\n");
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("\n");
}
printf("\nRoot初始化:\n");
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("\n");
}
//對結果取平均數,average=1/N,複數乘以常數在一開始定義
for (i = 0; i < N; i++)
{
Result[i] =mult1( IFFT(Source, N, Root[i], Result[i]) , average );
}
//結果表示
printf("\nResult計算結果:\n");
for (i = 0; i < N; i++)
{
printf("%.4f ", Result[i].real);
printf("+%.4fj ", Result[i].imag);
printf("\n");
}
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)));
}
}
歡迎指正!