求Q(x)模X^n + 1的余数多项式的FFT的逆变换IFFT
本文的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)));
	}
}
欢迎指正!
                    
                
                
            
        
浙公网安备 33010602011771号