FFTW使用小結

2021-09-14 07:24:28 字數 4763 閱讀 4921

***************=

fftw—fastest fourier transform in the west,是由 mit 的 matteo frigo 博士和 steven g. johnson 博士開發的乙個完全免費的軟體包。fftw 最初的 release 版本於 1997 年發布,最新的 release 版本 fftw-3.3.4。git路徑:

它是乙個 c 語言開發的庫,支援任意大小的、任意維數的資料的離散傅利葉變換(dft),並且還支援離散余弦變換(dct)、離散正弦變換(dst)和離散哈特萊變換(dht)

fftw 有三個版本的資料型別:double、float 和 long double,使用方法如下:

1.鏈結對應的庫(比如 libfftw3-3、libfftw3f-3、或 ibfftw3l-3)

2.包含同樣的標頭檔案 fftw3.h

將所有以小寫"fftw_「開頭的名字替換為"fftwf_」(float 版本)或"fftwl_"(long double 版本)。比如將 fftw_complex 替換為 fftwf_complex,將 fftw_execute

替換為 fftwf_execute 等。

3.所有以大寫"fftw_"開頭的名字不變

4.將函式引數中的 double 替換為 float 或 long double

5.最後,雖然 long double 是 c99 的標準,但你的編譯器可能根本不支援該型別,或它並不能提供比 double 更高的精度。

6.fftw_malloc 考慮了資料對齊,以便使用 simd 指令加速,所以最好不要用 c 函式malloc 替代,而且不要將 fftw_malloc、fftw_free 和 malloc、free、 delete 等混用。

盡量使用 fftw_malloc 分配空間,而不是使用的靜態陣列,因為靜態陣列是在棧上分配的,而棧空間較小;還因為這種方式沒有考慮資料對齊,不便應用simd 指令。

1.預設fftw編譯生成double型別,加入引數「–enable-single」或「–enable-float」編譯單精度(float),加入引數「–enable-long-double」支援長雙進度型別

2.另外,在arm平台上可增加「–enable-neon」,使能arm neon流**加速核心

用同乙個 fftw_plan 執行多個資料的變換

同乙個 fftw_plan 通過對輸入資料賦不同值來實現不同的變換,實際上還可以利用同乙個 fftw_plan 實現對不同輸入輸出資料的變換,也就是說可以有多個

輸入輸出資料陣列,各自進行變換,互不影響。當然這要滿足一定的條件:

1.輸入/輸出資料大小相等。

2.變換型別、是否原位運算不變。

3.對 split 陣列(指實虛部分開),實部和虛部的分割方式與方案建立時相同。

4.陣列的對齊方式相同。如果都是用 fftw_malloc 分配的則此項條件滿足,除非使用

fftw_unaligned 標誌

總結:是用現有plan必須滿足所有引數條件和申請plan時一致。

目前使用最廣泛,專案也只使用1d,並且輸入資料為實數,因此變化有兩種方法

1.將輸入部分擴充套件成虛數,即所有虛數為0,然後使用一維複數變化介面

fftw_plan fftw_plan_dft_1d(int n, fftw_complex *in, fftw_complex *out,

int sign, unsigned flags);

引數說明:

n – 複數資料點數

in/out – 輸入資料和輸出資料,可以相同(原位相同)

sign – fftw_forward(-1)正變換 fftw_backword(+1) 逆變換

flags – 主要有兩個引數 fftw_measure/fftw_estimate

fftw_measure 先進行預處理,對大資料(資料長度不變)連續fft變化效果明顯

fftw_estimate 直接構造乙個次最優的方案,非連續 實時選擇這種方案

2.使用1d實數dft變化,由於實數dft變化具有hmitian對稱性,所以只需計算n/2 + 1個輸出資料即可

需要注意:

a.如果採用原位運算則out空間必須》= 2*(n/2 + 1)

b.1d實數dft逆變換任何情況都會破壞in資料

c.當n為偶數,由nyquust取樣定理,第n/2個變化結果也是實數,所以可以把第0個和n/2個資料合併(n/2實部做0虛部),但實際上fftw沒有這樣實現,因為在多維資料時不相容

幾種方案測試

fft-dft :309us

fft-dft :345us

fft-dft :320us

fft-dft :349us

fft-dft :319us

fft-dft :320us

fft-dft :321us

fft-dft :324us

fft-dft :320us

fft-dft :319us

fft-dft :757919us

幅值:9.465116 相位:-169.040115

******************************=

使用r2c

fft-dft :208us

fft-dft :195us

fft-dft :198us

fft-dft :214us

fft-dft :212us

fft-dft :212us

fft-dft :221us

fft-dft :215us

fft-dft :214us

fft-dft :216us

fft-dft :564592us

幅值:9.465116 相位:-169.040115

******************************==

使用c2c 次最優方案

fft-dft :213us

fft-dft :204us

fft-dft :195us

fft-dft :195us

fft-dft :195us

fft-dft :196us

fft-dft :197us

fft-dft :196us

fft-dft :198us

fft-dft :197us

fft-dft :554788us

幅值:9.465116 相位:-169.040115

取樣點數為24000,進行1維複數/實數變化,引數選擇有fftw_measure/fftw_estimate

1.經測試,發現使用measure方案時,在第一構造plan時花費約1.5秒,而一次dft變化在300us-,構造的時間能做普通(fftw_estimate)5000次左右,故在一般場合fftw_estimate完全滿足需求。

2.實數fftw_estimate,時間上並沒有優於複數dft變化,只是記憶體開闢只有複數dft的一半。實數dft在構造plan時間上比複數慢,但變換比複數快,所以整體持平

3.最終選擇複數和實數 estimate方案

關於wisdom,翻譯自fftw官網

fftw -wisdom是一種實用工具來生成wisdom檔案,其中包含有關如何以最佳方式計算(傅利葉)變換不同大小的儲存的資訊。

wisdom 的大體思路就是把生成好的策略相關的配置資訊儲存在磁碟裡,然後在下次重新執行程式的時候,把策略相關的配置資訊重新載入到記憶體中,這樣在重新生成 plan 的時候就可以節約大量的時間。

fftw 提供了多種方式來生成wisdom檔案,使用時不必關心其中具體格式是怎麼樣,可以匯入/出到檔案/字串等

322 fftw_extern int x(export_wisdom_to_filename)(const char *filename);

323 fftw_extern void x(export_wisdom_to_file)(file *output_file);

324 fftw_extern char *x(export_wisdom_to_string)(void);

325 fftw_extern void x(export_wisdom)(x(write_char_func) write_char,

326 void *data);

327 fftw_extern int x(import_system_wisdom)(void);

328 fftw_extern int x(import_wisdom_from_filename)(const char *filename);

329 fftw_extern int x(import_wisdom_from_file)(file *input_file);

330 fftw_extern int x(import_wisdom_from_string)(const char *input_string);

331 fftw_extern int x(import_wisdom)(x(read_char_func) read_char, void *data);

wisdom 儲存起來的不是 plan 本身,而是和 plan 相關的配置資訊,例如記憶體、暫存器等。故在匯入wisdom後還是需要執行plan初始化。

example:

fftw_export_wisdom_to_filename(「wisdom.conf」);

p_str = fftw_export_wisdom_to_string();

fftw_export_wisdom_from_filename("wisdom.conf");

fftw_export_wisdom_from_string(p_str);

windows Qt下使用fftw庫

環境 win7 qt 5.1.0 正如官網所述 需要在cmd下執行以下命令生成lib庫 lib def libfftw3 3.def lib def libfftw3f 3.def lib def libfftw3l 3.def 生成 libfftw3 3.lib libfftw3 3f.lib l...

FFTW庫安裝與使用

fftw是乙個用c語言編寫 支援一維和多維變換 支援任意大小輸入 支援實數和複數的數字傅利葉變換軟體庫。該庫由mit的matteo frigo和steven g.johnson編寫。使用cmake工具,可以呼叫find package函式查詢fftw3庫,故在cmakelists.txt檔案中新增如...

使用fftw3 3進行余弦變換

使用fftw3 3進行余弦變換 余弦變換的主要型式也有4種。基於fftw3 3,定義兩個函式 其原型如下 source code inline void dct long long double double int inline void idct long long double double ...