機子裏的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); /* repeat as needed*/
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參數
下面的是如何使用的一個例子
/*****************************
* filename: test_fftw.cpp
* author : Tiao Lu
* Company : School of Mathematical Sciences, Peking University
* 編譯命令: g++ -o test_fftw.exe test_fftw.cpp -lfftw3
* Date : September 30th, 2007
* Description: This code is an example to show the use of the free code FFTW, which implements the Fast Fourier Trasformation algorithm.
*/
#include <complex>
#include <fftw3.h>
#include <math.h>
#include <iostream>
#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 <N;i ++) {
in[i][0]=i;
in[i][1]=0.0;
}
fftw_execute(p);
for(int i=0;i <N;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<double> temp = 0.0;
for(int k =0; k < N; k ++){
double pi = 4*atan(1.0);
temp += exp(complex<double>(0.0,-2.0*pi*3*k/N))*complex<double>(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 <N;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 <N;i ++){
cout<<in[i][0]<<" "<<in[i][1]<<endl;
}
fftw_destroy_plan(p);
fftw_destroy_plan(p1);
return 1;
}