Bluesteinのアルゴリズム 単語

ブルースタインノアルゴリズム

3.7千文字の記事

Bluesteinのアルゴリズムとは、任意の長さの離散データ高速フーリエ変換するためのFFTアルゴリズムである。

概要

ここでは、元のデータaを周期Nの周期的データと仮定する。

通常のフーリエ変換は任意の長さの配列を計算できるがO(N2)の計算量が必要であり、FFTはO(NlogN)で計算できるがNが2の冪に限定されるという問題がある。

Bluesteinのアルゴリズムは任意の長さの配列をO(NlogN)で計算できるアルゴリズムである。
原理は、フーリエ変換み込みに変換して、み込みをFFTで計算するというものである。み込みは定義通りだとO(N2)の計算量になる。

配列の長さを2倍以上に拡し、アルゴリズムの一部に2の冪のFFTを3回含むので、FFTべて6~8倍程度の計算時間になる。最適化しないうちは10倍以上はかかると想定しておいた方がよいだろう。

解説

WN(m)=exp(πim/N)とする。
長さNのデータa=(a(0), a(1), ...,a(N-1))の離散フーリエ変換定義は以下の通り。

F(u)=F(a)(u)=(1/N)ΣN-1n=0a(n)WN(-2un)

(u-n)2=u2-2un+n2 であることに注意すると、2un=u2+n2-(u-n)2 なので、

WN(-2un)=WN(-u2-n2+(u-n)2)
F(u)=(1/NN-1n=0a(n)WN(-u2)WN(-n2)WN((u-n)2)
      =(1/N)WN(-u2)ΣN-1n=0a(n)WN(-n2)WN((u-n)2)

ここで、

a(m)WN(-m2)=p(m)
WN(m2)=q(m)

と置くと、

F(u)=q(-u)(1/N)ΣN-1n-0p(n)q(u-n) = q(-u)(p*q)(u) = q(-u)r(u)

となるので、a(n)のフーリエ変換をp(n)とq(n)のみ込みに置き換えることができる。
p(n)とq(n)のみ込みはフーリエ変換→各成分の積→フーリエ逆変換で置き換えることができる。
また、p(n)とq(n)を適切な構造の長さが2の冪の配列に拡すれば、高速フーリエ変換を適用できるようになる。
q(n+N)=WN(n2+N(2n+N))=q(n)なので、拡されたp(n),q(n)は以下の通り。

p’(n) = p(n) = a(n)WN(-n2)  (0≦n<N)
p’(n) = 0               (N≦n<2M)
q’(n) = WN(n2)              (0≦n<2M)

Mは、2M-1<2N≦2M となることが条件。

後に得られた配列F'(u)は元の配列F(u)を含むので、F'(u)から適切な位置で長さNの分だけ切り取る。配列を長くすることが原因でみ込みの振幅がN/M倍に変わるので最後にM/N倍する必要がある。

まとめ

全体のアルゴリズムは以下のようになる。k,mは自然数

aを受け取る
↓  
   → F’(u)=r(u)q(-u)を得る
aから長さ2Mのp’(k),q’(k)を生成 
  ↑ F'(u)からF(u)を取り出す
p(k), q(k)をP(m), Q(m)に高速フーリエ変換
  ↑ 振幅を整える
R(m)=P(m)Q(m)を逆高速フーリエ変換 →↑   Aを得て終了

実装

VBAでは以下のようになる。データ部分の実数列Re()、全て0の構成された虚数列Im()を受け取り、直接書き換える。
2の冪のFFTと逆FFT実装済みとする。

Function Bulestein(Re(), Im(), N)
Pi=3.1415926535
M = 1
While M < N
M = 2 * M
Wend
'==========================================2の冪には直接FFTを適用
If N = M Then    
Call FFT(Re(), Im(), N)
'==========================================アルゴリズム開始
Else
M = 2 * M
Dim C() As Variant
ReDim C(M)
Dim S() As Variant
ReDim S(M)
Dim WC() As Variant
ReDim WC(M)
Dim WS() As Variant
ReDim WS(M)

For I = 0 To M - 1 '================================q(m)
WC(I) = Cos(Pi * I * I / N)
WS(I) = Sin(Pi * I * I / N)
Next I
For I = 0 To N - 1 '=================================p(m)
C(I) = Re(I) * WC(I) + Im(I) * WS(I)
S(I) = Im(I) * WC(I) - Re(I) * WS(I)
Next I
For I = N To M - 1
C(I) = 0
S(I) = 0
Next I
'================================================================み込み開始
Call FFT(C(), S(), M)
Call FFT(WC(), WS(), M)

For I - 0 to M - 1
X = C(I) * WC(I) - S(I) * WS(I)
Y = S(I) * WC(I) + C(I) * WS(I)
C(I) = X
S(I) = Y
Next I

Call FFTI(C(), S(), M)
'=================================================================み込み終了
Y = M / N  '===========================================フーリエ変換に合わせる係数
For I = 0 To N - 1
X = I + N '===========================================切り取る位置
Re(I) = (C(X) * Cos(Pi * X * X / N) + S(X) * Sin(Pi * X * X / N)) * Y
Im(I) = (S(X) * Cos(Pi * X * X / N) - C(X) * Sin(Pi * X * X / N)) * Y
Next I
End If
End Function

逆Bluesteinアルゴリズム

当然逆変換も存在する。フーリエ逆変換の定義から、

F-1(u)=ΣN-1n=0a(n)WN(2nu)=q(u)ΣN-1n=0p(n)q(u+n)

となり、み込みではなく相関関数を計算することになる。
全体としては係数と一か所だけ逆FFTに変えるだけで逆変換になる。

赤色が変更した部分。

Function BulesteinI(Re(), Im(), N)
Pi=3.1415926535
M = 1
While M < N
M = 2 * M
Wend
'==========================================2の冪には直接FFTを適用
If N = M Then    
Call FFTI(Re(), Im(), N)   '===========逆FFT

'==========================================アルゴリズム開始
Else
M = 2 * M
Dim C() As Variant
ReDim C(M)
Dim S() As Variant
ReDim S(M)
Dim WC() As Variant
ReDim WC(M)
Dim WS() As Variant
ReDim WS(M)

For I = 0 To M - 1 '================================q(m)
WC(I) = Cos(Pi * I * I / N)
WS(I) = Sin(Pi * I * I / N)
Next I
For I = 0 To N - 1 '=================================p(m)
C(I) = Re(I) * WC(I) + Im(I) * WS(I)
S(I) = Im(I) * WC(I) - Re(I) * WS(I)
Next I
For I = N To M - 1
C(I) = 0
S(I) = 0
Next I
'================================================================み込み開始
Call FFTI(C(), S(), M) '================================逆FFT
Call FFT(WC(), WS(), M)

For I - 0 to M - 1
X = C(I) * WC(I) - S(I) * WS(I)
Y = S(I) * WC(I) + C(I) * WS(I)
C(I) = X
S(I) = Y
Next I

Call FFTI(C(), S(), M)
'=================================================================み込み終了
Y = 1  '===========================================フーリエ変換に合わせる係数
For I = 0 To N - 1
X = I '===========================================切り取る位置
Re(I) = (C(X) * Cos(Pi * X * X / N) + S(X) * Sin(Pi * X * X / N)) * Y
Im(I) = (S(X) * Cos(Pi * X * X / N) - C(X) * Sin(Pi * X * X / N)) * Y
Next I
End If
End Function

関連項目

この記事を編集する

掲示板

掲示板に書き込みがありません。

おすすめトレンド

ニコニ広告で宣伝された記事

記事と一緒に動画もおすすめ!
もっと見る

急上昇ワード改

最終更新:2025/12/13(土) 13:00

ほめられた記事

最終更新:2025/12/13(土) 12:00

ウォッチリストに追加しました!

すでにウォッチリストに
入っています。

OK

追加に失敗しました。

OK

追加にはログインが必要です。

           

ほめた!

すでにほめています。

すでにほめています。

ほめるを取消しました。

OK

ほめるに失敗しました。

OK

ほめるの取消しに失敗しました。

OK

ほめるにはログインが必要です。

タグ編集にはログインが必要です。

タグ編集には利用規約の同意が必要です。

TOP