windows下使用fftw进行傅里叶变换及其编程实例

       傅里叶变换应该是上大二的时候《信号与系统》课上学过,上研后在《数字信号处理》课上又学了一遍。当初一直在想傅里叶变换到底有什么用呢?什么时候能用上呢?时间如梭,没想到毕业四年后,一个小项目要用到傅里叶变换,喜大普奔啊,当初晦涩的概念、眼晕的公式,终于没白学。是的, 其实 任何知识都不是白学的,即使工作中一直用不到傅里叶变换,至少思维得到了锻炼,都是有益的 在应用傅里叶变换过程中,可以按照公式自己编程实现,也可以使用已有的开源傅里叶变换函数库。经过查阅资料,本人选用fftw函数库来进行傅里叶变换,因为 fftw 官网上提到说该函数库性能非常出众,甚至可以和同类型的商业软件相竞争。fftw官网地址为: http://www.fftw.org/。
       一、fftw下载
       由于本人是在windows平台开发,于是到下面链接:http://www.fftw.org/install/windows.html下载已编译版本。如下图所示,该图信息量很大,既有32/64两个版本的下载链接,同时还有生成lib文件命令。即32位系统命令为: lib /def:libfftw3-3.def,而64位系统为: lib /machine:x64 /def:libfftw3-3.def。
                           windows下使用fftw进行傅里叶变换及其编程实例_第1张图片
       下载解压后,会发现只有dll和头文件,在没有lib文件时,使用fftw库时会比较繁琐。于是在应用fftw编程前还是动手先生成lib文件。方法很简单,首先打开VS命令提示工具。本人使用的开发工具为VS2005,如下图所示:
                                                         windows下使用fftw进行傅里叶变换及其编程实例_第2张图片
打开后,cd到已下载的fftw文件目录,然后执行前面提到的lib生成命令,如下图所示:
                                   windows下使用fftw进行傅里叶变换及其编程实例_第3张图片
命令执行完毕后,即可在当前目录内看到新生成的lib文件,我这边分别生成了double、float、long double三个版本,实际使用时可根据项目需要,选择相应精度的版本。生成的lib库文件如下图所示:
                                                             windows下使用fftw进行傅里叶变换及其编程实例_第4张图片



       二、简单编程实例
       有了头文件、lib/dll文件,那就什么都有了。新建一个工程,马上用起来吧。下面为一个非常简单的编程实例,主要完成实数傅里叶变换,输入为正弦曲线,输出为傅里叶变换的幅度谱。
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "include/fftw3.h"
#pragma comment(lib, "libfftw3-3.lib") // double版本
// #pragma comment(lib, "libfftw3f-3.lib")// float版本
// #pragma comment(lib, "libfftw3l-3.lib")// long double版本

#define PI 3.1415926

int main()
{
	int len = 8;
	double *in = NULL;
	// 如果要使用float版本,需先引用float版本的lib库,然后在fftw后面加上f后缀即可.
	fftw_complex *out = NULL;// fftwf_complex --> 即为float版本
	fftw_plan p;
	in  = (double *)fftw_malloc(sizeof(double) * len);
	out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * len);
	double dx = 1.0 / len;

	// 输入纯实数
	for (int i = 0; i < len; i++)
	{
		in[i] = sin(2*PI * dx*i) + sin(4*PI * dx*i);

		printf("%.2f ", in[i]);
	}
	printf("\n\n");

	// 傅里叶变换
	p = fftw_plan_dft_r2c_1d(len, in, out, FFTW_ESTIMATE);
	fftw_execute(p);

	// 输出幅度谱
	for (int i = 0; i < len; i++)
	{
		float len = sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1]);
		printf("%.2f ", len);
	}
	printf("\n");

	// 释放资源
	fftw_destroy_plan(p);
	fftw_free(in);
	fftw_free(out);

	system("pause");
	return 0;
}
       运行结果如下图所示,从结果来看,在频率为1及2两个位置有幅度输出,这与输入的频率为1及2的两个叠加正弦波吻合,结果正确。(8月23日补充:由于实数DFT变换的输出序列具有共轭对称性,因此fftw_plan_dft_r2c_1d()函数返回的序列实际长度为len /2 + 1,因此上述代码在为out分配内存时仅需分配len / 2 + 1即可。)
                                                  


你可能感兴趣的:(傅里叶变换,FFTW)