FFT加速多項式乘法C語言版(基2FFT)

本文代碼中FFT使用遞歸版本實現

FFT加速多項式乘法原理不多說了,直接貼代碼如下:

在vs2017上測試成功

#include "pch.h"
#define _CRT_SECURE_NO_WARNINGS
#include "stdlib.h"
#include "math.h"
#include "stdio.h"


#define N 8
#define MAXN 100

#define Pi  3.1415927   //定義圓周率Pi
#define LEN sizeof(struct Compx)  //定義複數結構體大小

//-----定義複數結構體-----------------------
typedef 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 sub(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 add(struct Compx a, struct Compx b)
{
	struct Compx c;
	c.real = a.real + b.real;
	c.imag = a.imag + b.imag;
	return(c);
}

void fft(Compx *a, int n, int inv);

int main()
{
	int i;

	int x[N] = { 0 }, y[N] = { 0 };

	printf("\nN=%d\n" , N);
	printf("\n輸入兩個多項式的係數,輸入係數爲N多項式長度的一半\n");
	printf("\n輸入第一個多項式的係數\n");
	for (i = 0; i < N/2; i++)
	{
		scanf("%d", &x[i]);
	}

	printf("\n輸入第二個多項式的係數\n");
	for (i = 0; i < N/2; i++)
	{
		scanf("%d", &y[i]);
	}

	struct  Compx * a = (struct Compx *)malloc(N*LEN);			//爲結構體分配存儲空間
	struct  Compx * b = (struct Compx *)malloc(N*LEN);
	struct  Compx * c = (struct Compx *)malloc(N*LEN);

	//初始化======================================= 
	printf("\na多項式初始化:\n");
	for (i = 0; i < N; i++)
	{
		a[i].real = x[i];
		a[i].imag = 0;
		printf("%.4f ", a[i].real);
		printf("+%.4fj  ", a[i].imag);
		printf("\n");
	}
	printf("\nb多項式初始化:\n");
	for (i = 0; i < N; i++)
	{
		b[i].real = y[i];
		b[i].imag = 0;
		printf("%.4f ", b[i].real);
		printf("+%.4fj  ", b[i].imag);
		printf("\n");
	}
	printf("\n結果c多項式初始化:\n");
	for (i = 0; i < N; i++)
	{
		c[i].real = 0;
		c[i].imag = 0;
		printf("%.4f ", c[i].real);
		printf("+%.4fj  ", c[i].imag);
		printf("\n");
	}

	fft(a, N, 1);

	printf("\n第一個多項式FFT計算結果:\n");
	for (i = 0; i < N; i++)
	{
		printf("%.4f ", a[i].real);
		printf("+%.4fj  ", a[i].imag);
		printf("\n");
	}

	fft(b, N, 1);

	printf("\n第二個多項式FFT計算結果:\n");
	for (i = 0; i < N; i++)
	{
		printf("%.4f ", b[i].real);
		printf("+%.4fj  ", b[i].imag);
		printf("\n");
	}

	for (i = 0; i < N; i++)
		a[i] = mult(a[i] , b[i]);

	fft(a, N, -1);
	for (i = 0; i < N; i++) {
		c[i].real = a[i].real / N;
		c[i].imag = a[i].imag / N;
	}
		
	printf("\n乘積多項式結果:\n");
	for (i = 0; i < N; i++)
	{
		printf("%.4f ", c[i].real);
		printf("+%.4fj  ", c[i].imag);
		printf("\n");
	}

	return 0;
}

void fft(Compx *a, int n, int inv) {
	if (n == 1)return;
	int mid = n / 2;
	static Compx b[MAXN];
	int i;
	for (i = 0; i < mid; i++) {
		b[i] = a[i * 2];
		b[i + mid] = a[i * 2 + 1];
	}
		
	for (i = 0; i < n; i++)
		a[i] = b[i];
	fft(a, mid, inv);
	fft(a + mid, mid, inv);//分治
	for (i = 0; i < mid; i++)
	{
		Compx x;
		x.real = cos(2 * Pi*i / n);
		x.imag = inv * sin(2 * Pi*i / n);

		b[i] = add(a[i], mult(x, a[i + mid]));
		b[i + mid] = sub(a[i] , mult(x , a[i + mid]));
	}
	for (i = 0; i < n; i++)
		a[i] = b[i];
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章