Created
October 23, 2012 12:12
-
-
Save hirosof/3938429 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "HSFFT.h" | |
| #include <Windows.h> | |
| #ifndef __HSFFT_CPP__ | |
| #define __HSFFT_CPP__ | |
| //2を底としたlog(対数)関数 for FFT・IFFT | |
| unsigned int HS_fft_log2(unsigned int r){ | |
| double log_num , integer; | |
| log_num = log((double)r) / log(2.0); | |
| if(modf(log_num , &integer))return 0; | |
| else return (unsigned int)integer; | |
| } | |
| //FFTの回転因子 | |
| HSFFT_CMPLEX HS_fft_twfac(int n,int k){ | |
| HSFFT_CMPLEX cmp; | |
| double buf; | |
| buf = (2.0 * M_PI * k)/n; | |
| cmp.Real = cos(buf); | |
| cmp.Imaginary = -sin(buf); | |
| return cmp; | |
| } | |
| //FFTのバタフライ計算 | |
| int HS_fft_butterfly(LPHSFFT_CMPLEX input,LPHSFFT_CMPLEX output,int n ,int k){ | |
| LPHSFFT_CMPLEX ia , ib , oa , ob; | |
| HSFFT_CMPLEX eb; | |
| double obr,obi; | |
| if(!input || !output)return 0; | |
| //入力用 a,b | |
| ia = input; | |
| ib = input + 1; | |
| //出力用 a,b | |
| oa = output; | |
| ob = output + 1; | |
| /*計算*/ | |
| //oa = ia + ib | |
| oa->Real = ia->Real + ib->Real; | |
| oa->Imaginary = ia->Imaginary + ib->Imaginary; | |
| //回転因子 | |
| eb = HS_fft_twfac(n,k); | |
| //ob = ia-ib (行程1) | |
| ob->Real = ia->Real - ib->Real; | |
| ob->Imaginary = ia->Imaginary - ib->Imaginary; | |
| //ob * eb (行程2) | |
| //途中計算をobr(実部)、obi(虚部)に代入 | |
| obr = eb.Real * ob->Real; | |
| obr -= eb.Imaginary * ob->Imaginary; | |
| obi = eb.Imaginary * ob->Real; | |
| obi += eb.Real * ob->Imaginary; | |
| //計算結果を代入 | |
| ob->Real = obr; | |
| ob->Imaginary = obi; | |
| return 1; | |
| } | |
| //ビットリバース | |
| unsigned __int32 HS_fft_BitReverseU32 (unsigned __int32 num,int bits){ | |
| unsigned __int32 rev_num; | |
| int cnt; | |
| if(bits > 32)return 0; | |
| else if(bits == 0) bits = 32; | |
| for( rev_num = cnt = 0 ; cnt < bits ; cnt++ ) | |
| if((num & ( 1 << cnt ))) | |
| rev_num += (1 << ( bits - 1 - cnt )); | |
| return rev_num; | |
| } | |
| //FFT・IFFT関数 | |
| int HS_fft_exec(LPHSFFT_CMPLEX input, LPHSFFT_CMPLEX output , unsigned int N,unsigned int inverse_flag){ | |
| unsigned int k_x , num_stage , stage_cnt , sub_cnt , item_cnt; | |
| unsigned int k_plus , index_plus , idx; | |
| unsigned int index_out; | |
| HSFFT_CMPLEX but_i[2],but_o[2]; | |
| //FFT or IFFT (回転因子の符号) | |
| k_x = (inverse_flag) ? -1 : 1 ; | |
| //ステージ数の計算 | |
| num_stage = HS_fft_log2(N); | |
| //引数に不備が有る場合は0を返す | |
| if(!num_stage || !input || !output)return 0; | |
| //FFT・IFFT ステージループ | |
| for(stage_cnt = 0,index_plus = N; stage_cnt < num_stage ; stage_cnt++){ | |
| //バタフライ演算で使用するペアを計算する際に使用するもの | |
| index_plus >>= 1; //index_plusを2で割る(1ビット右にシフトで実装) | |
| //バタフライ演算で使用する指数を計算する際に使用するもの | |
| k_plus = 1 << stage_cnt; | |
| //1ステージ当たりの処理ループ | |
| for(sub_cnt = 0 ; sub_cnt < k_plus ; sub_cnt++){ | |
| //1アイテム当たりの処理 | |
| for(item_cnt = 0 ; item_cnt < index_plus ; item_cnt++){ | |
| //インデックス(配列要素番号) | |
| idx = index_plus*sub_cnt*2 + item_cnt; | |
| //バタフライ演算 準備 | |
| if(stage_cnt){ | |
| but_i[0] = *(output + idx); | |
| but_i[1] = *(output + idx + index_plus); | |
| }else{ | |
| but_i[0] = *(input + idx); | |
| but_i[1] = *(input + idx + index_plus); | |
| } | |
| //バタフライ演算 実行 | |
| HS_fft_butterfly(but_i , but_o , N , k_plus * item_cnt * k_x); | |
| //バタフライ演算 結果代入 | |
| *(output + idx) = but_o[0]; | |
| *(output + idx + index_plus) = but_o[1]; | |
| } | |
| } | |
| } | |
| //IFFTならば正規化をする | |
| if(inverse_flag){ | |
| for(item_cnt=0 ;item_cnt < N ; item_cnt++){ | |
| (output + item_cnt)->Real /= N; | |
| (output + item_cnt)->Imaginary /= N; | |
| } | |
| } | |
| //並べ替え | |
| for(item_cnt=0 ;item_cnt < N ; item_cnt++){ | |
| //カウンタ値をビット逆順する | |
| index_out = HS_fft_BitReverseU32(item_cnt,num_stage); | |
| //必要なデータを交換する | |
| if(index_out > item_cnt){ | |
| but_o[0] = *(output + item_cnt); | |
| *(output + item_cnt) = *(output + index_out); | |
| *(output + index_out) = but_o[0]; | |
| } | |
| } | |
| return 1; | |
| } | |
| int HS_rfft_exec(double *input, LPHSFFT_CMPLEX output, unsigned int N){ | |
| unsigned int k_x , num_stage , stage_cnt , sub_cnt , item_cnt; | |
| unsigned int k_plus , index_plus , idx; | |
| unsigned int index_out; | |
| HSFFT_CMPLEX but_i[2],but_o[2]; | |
| //回転因子の符号 | |
| k_x = 1; | |
| //ステージ数の計算 | |
| num_stage = HS_fft_log2(N); | |
| //引数に不備が有る場合は0を返す | |
| if(!num_stage || !input || !output)return 0; | |
| //FFTステージループ | |
| for(stage_cnt = 0,index_plus = N; stage_cnt < num_stage ; stage_cnt++){ | |
| //バタフライ演算で使用するペアを計算する際に使用するもの | |
| index_plus >>= 1; //index_plusを2で割る(1ビット右にシフトで実装) | |
| //バタフライ演算で使用する指数を計算する際に使用するもの | |
| k_plus = 1 << stage_cnt; | |
| //1ステージ当たりの処理ループ | |
| for(sub_cnt = 0 ; sub_cnt < k_plus ; sub_cnt++){ | |
| //1アイテム当たりの処理 | |
| for(item_cnt = 0 ; item_cnt < index_plus ; item_cnt++){ | |
| //インデックス(配列要素番号) | |
| idx = index_plus*sub_cnt*2 + item_cnt; | |
| //バタフライ演算 準備 | |
| if(stage_cnt){ | |
| but_i[0] = *(output + idx); | |
| but_i[1] = *(output + idx + index_plus); | |
| }else{ | |
| but_i[0].Real = *(input + idx); | |
| but_i[1].Real = *(input + idx + index_plus); | |
| but_i[0].Imaginary = but_i[1].Imaginary = 0; | |
| } | |
| //バタフライ演算 実行 | |
| HS_fft_butterfly(but_i , but_o , N , k_plus * item_cnt * k_x); | |
| //バタフライ演算 結果代入 | |
| *(output + idx) = but_o[0]; | |
| *(output + idx + index_plus) = but_o[1]; | |
| } | |
| } | |
| } | |
| //並べ替え | |
| for(item_cnt=0 ;item_cnt < N ; item_cnt++){ | |
| //カウンタ値をビット逆順する | |
| index_out = HS_fft_BitReverseU32(item_cnt,num_stage); | |
| //必要なデータを交換する | |
| if(index_out > item_cnt){ | |
| but_o[0] = *(output + item_cnt); | |
| *(output + item_cnt) = *(output + index_out); | |
| *(output + index_out) = but_o[0]; | |
| } | |
| } | |
| return 1; | |
| } | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //インクルード部 | |
| #include <stdio.h> | |
| #define _USE_MATH_DEFINES /* math.h内の定数を使う */ | |
| #include <math.h> | |
| #include <memory.h> | |
| #include <windows.h> | |
| #ifndef __HSFFT_H__ | |
| #define __HSFFT_H__ | |
| //複素数構造体定義部 | |
| typedef struct{ | |
| double Real; | |
| double Imaginary; | |
| }HSFFT_CMPLEX,*PHSFFT_CMPLEX,*LPHSFFT_CMPLEX; | |
| //プロトタイプ宣言部 | |
| //2を底としたlog(対数)関数 | |
| unsigned int HS_fft_log2(unsigned int); | |
| //FFTの回転因子 | |
| //twfacは『「Tw」iddle「fac」tor』より | |
| HSFFT_CMPLEX HS_fft_twfac(int,int); | |
| //FFTのバタフライ計算 | |
| int HS_fft_butterfly(LPHSFFT_CMPLEX,LPHSFFT_CMPLEX,int,int); | |
| //ビットリバース | |
| unsigned __int32 HS_fft_BitReverseU32 (unsigned __int32,int); | |
| //FFT・IFFT関数 | |
| int HS_fft_exec(LPHSFFT_CMPLEX, LPHSFFT_CMPLEX , unsigned int, unsigned int); | |
| int HS_rfft_exec(double*, LPHSFFT_CMPLEX , unsigned int); | |
| #endif /*__HSFFT_H__*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment