fftw庫的window安裝和linux安裝和例子

機子裏的FFTW庫下了很長時間了,總也沒有去搞。唉,有很多東西就是這樣,千方百計搞過來,搞到手了就晾在那裏了。記得《黃生借書說》裏面說得對啊書非借不能讀也

好了,感慨完畢。歸入正題。

WindowsFFTW庫的安裝

1、  從網址http://www.fftw.org/install/windows.html上獲得FFTWwindows 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.li3lib文件及 fftw3.h 文件所在的目錄。也就是在vc++tools->options Directories選項中的Include FilesLibrary Files中把這兩個目錄加上,使得以後VC編譯的時候知道該到哪個目錄中去找。

6、  最後一步就是,在你新建工程的時候,記得#includefftw3.h,然後把你要用的lib寫到Project->setting->link->General裏面的Object/library modules裏面去。

7、  下面,你就可以放心大膽地去使用fftw的庫編程了。爲了熟悉FFTW的調用方式和數據結構,你還可以從http://www.fftw.org/#documentation下載一份manual好好鑽研鑽研。

 

可能出現的錯誤:

1.      LNK1181cannot 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;
}

發佈了76 篇原創文章 · 獲贊 57 · 訪問量 76萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章