红联Linux门户
Linux帮助

FFT的C语言库FFTW的Windows和linux安装使用方法

发布时间:2016-05-23 10:33:36来源:linux网站作者:叶落孤天

机子里的FFTW库下了很长时间了,总也没有去搞。唉,有很多东西就是这样,千方百计搞过来,搞到手了就晾在那里了。记得《黄生借书说》里面说得对啊“书非借不能读也”。

好了,感慨完毕。归入正题。


Windows下FFTW库的安装

1、从网址http://www.fftw.org/install/windows.html上获得FFTW的windows dll预编译版本;

2、解压缩文件,打开windows命令行窗口,就是那个cmd窗口啦。然后把当前目录转换到你解压缩文件的目录下。

3、执行以下3个指令(在ix86和/def:libfftw3-3.def之间没有加空格会造成错误)

lib /machine:ix86 /def:libfftw3-3,def
lib /machine:ix86 /def:libfftw3f-3.def
lib /machine:ix86 /def:libfftw3l-3.def

这会在该目录下建三个相应的dll文件和lib文件。注意第三个.def文件中的“3l-3”中的是字母L的小写,不是数字一。因为这个问题,我搞了半个小时,呵呵。

4、将libfftw3l-3.dll, libfftw3f-3.dll, libfftw3-3.dll 文件复制到文件夹system32中。这一步是为了你以后都不用在你的可执行文件所在的文件夹中带上这3个拖油瓶,因为系统直接会去system32中找。

5、在 VC 中指定 libfftw3l-3.lib, libfftw3f-3.lib, libfftw3-3.li這3個lib文件及 fftw3.h文件所在的目录。也就是在vc++的tools->options的 Directories选项中的Include Files和Library Files中把这两个目录加上,使得以后VC编译的时候知道该到哪个目录中去找。

6、最后一步就是,在你新建工程的时候,记得#include“fftw3.h”,然后把你要用的lib写到Project->setting->link->General里面的Object/library modules里面去。

7、下面,你就可以放心大胆地去使用fftw的库编程了。为了熟悉FFTW的调用方式和数据结构,你还可以从http://www.fftw.org/#documentation下载一份manual好好钻研钻研。


可能出现的错误:

1.LNK1181:cannot open input file“…”: 出现这个错误的原因有: (1)你文件名打错了; (2) 你的当前目录不对,当前目录应该是你解压后的文件目录。

2.源文件编译时报找不到lib,那是因为你第5步或第6步没做好,建议重做一下第5步和第6步。


使用FFTW编写测试程序
上面的搞好后,就写一个小的测试代码试一下效果。我就抄了一个网上的代码:

#include "fftw3.h"
int main()
{
fftw_complex *in, *out;
fftw_plan p;
int N= 8;
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
for( int i=0; i < N; i++)
{
in[i][0] = 1.0;
in[i][1] = 0.0;
printf("%6.2f ",in[i][0]);
}
printf("\n");  // in 是输入的数据
p=fftw_plan_dft_1d(N,in,out, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(p);
for(int j = 0;j < N;j++)
{
printf("%6.2f ",out[j][0]);
}
printf("\n");
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
return 0;
}

程序给了一个直流的时域数据,应该出来一个只有直流分量的DFT数据。


Linux下FFTW库的安装

FFTW(the Fastest Fourier Transform in the West)库是由MIT(Massachusetts Institute of Technology)的Matteo Frigo和Steven G. Johnson开发的,用于一维和多维实数或复数的离散傅里叶变换。

1.下载 fftw-2_1_3_tar.gz(www.fftw.org, or www.rpmfind.net )

2.tar zxvf fftw-2_1_3_tar.gz  展开压缩文件

3.在Linux中安装FFTW:

a.   

./configure --enable-type-prefix --prefix=/usr/local/fftw --with-gcc --disable-fortran --enable-i386-hacks

其中,

--enable-type-prefix    参数是为了同时使用single precision(单精度)和double precision(双精度),如果不使用它,最后只有以rfftw开头的文件被安装(real fftw);

--prefix=                      参数是设定安装目录;

--with-gcc                    使用gcc编译器;

--disable-fortran         参数为了不包含Fortran调用的机制;

--enable-i386-hacks   为Pentium和x86以后的CPU优化gcc的编译速度。

b.

make   编译

c.

make install   安装,这一次安装完后,在安装目录中存在以dfftw和drfftw开头文件,但没有sfftw开头的文件

d.

make clean   还需要安装一次,先清除

e.

./configure --enable-float --enable-type-prefix --prefix=/usr/local/fftw --with-gcc --disable-fortran --enable-i386-hacks

其中,--enable-float  为了生成单精度计算的头文件和库文件,即以sfftw开头的文件。

f.

make  重新编译

g.

make install  再一次安装,安装完后,目录中便会同时存在sfftw和dfftw开头的文件(用于复数函数/complex function的FFT变换)和srfftw与drfftw开头的文件(用于实数函数的FFT变换)

例如,如果需要用到双精度的实数FFT变换/FFTs,那么在编译的链接命令中需要按如下顺序加入
-ldrfftw -ldfftw参数


下面的是如何使用的一个例子

#include
#include
#include
#include

#define N 10
using namespace std;
int main(int argc, char * argv[]){

fftw_complex in[N], out[N];
fftw_plan p;

//一维dft,in 输入,out输出,FFTW_FORWARD 表示 exp 上指数是负号
// out = F in
//where out and in are two vectors of the same length n, and F is a n-by-n matrix with the (j,k) element
// F jk = exp(-i 2 pi j k /n). i 是虚数单位.

p=fftw_plan_dft_1d(N,in,out,FFTW_FORWARD,FFTW_MEASURE);
for(int i=0;i
in[i][0]=i;
in[i][1]=0.0;
}
fftw_execute(p);
for(int i=0;i
cout<<out[i][0]<<" "<<out[i][1]<<endl;
}
//验证是否 out[3] = \sum_{k=0}^{N-1}exp(-i 2pi 3 k/N)in[k]
complex temp = 0.0;
for(int k =0; k < N; k ++){
double pi = 4*atan(1.0);
temp += exp(complex(0.0,-2.0*pi*3*k/N))*complex(in[k][0],in[k][1]);
}
cout<<"out[3] is "<<temp<<endl;

fftw_complex out1[N];

fftw_plan p1;
//一维dft,in 输入,out输出,FFTW_BACKWARD 表示 exp 上指数是正号
// out = IF in
//where out and in are two vectors of the same length n, and IF is a n-by-n matrix with the (j,k) element
// IF jk = exp( +i 2 pi jk/n). i 是虚数单位.

p1=fftw_plan_dft_1d(N,out1,in,FFTW_BACKWARD,FFTW_MEASURE);

for(int i=0;i
out1[i][0]=out[i][0];
out1[i][1]=out[i][1];
}

fftw_execute(p1);
//注意这里得到的 in 并不是和原来的in 的数值不同,比较之后发现,现在的in
// 是原来的 in 的 N 倍。原因是这里的定义的逆傅立叶变换没有除以 N.
//这和课本中定义的逆傅立叶变换不同。
for(int i=0;i
cout<<in[i][0]<<" "<<in[i][1]<<endl;
}
fftw_destroy_plan(p);
fftw_destroy_plan(p1);
return 1;
}


本文永久更新地址:http://www.linuxdiyf.com/linux/20877.html