とまぁ、そんなわけで、実際に1次元データに対してガウシアンフィルタを計算してみます。
ACLS
XSCREEN 1
OPTION STRICT
OPTION DEFINT
VAR N%=512,L%=63
DIM SIGNAL#[2048],FILTER#[2048] '信号長+フィルタ長は2048以内
DIM BLURED0#[2048],BLURED1#[2048] 'フィルタリング結果
DIM FFTR#[2048],FFTJ#[2048] 'FFT用バッファ
DIM CONVOLR#[2048],CONVOLJ#[2048] '畳み込み用バッファ
DIM T#[2048]
'ガウシアンフィルタの係数を計算(因果的でない)
DEF GAUSS A[],N
VAR I%
A[0]=POW(2,-N+1) 'N>31でオーバーフローするため修正
FOR I%=1 TO (N>>1)-1
A[I%]=A[I%-1]*(N-I%)/I%
A[N-I%-1]=A[I%]
NEXT I%
END
'愚直に計算
DEF FIR0 O,IN,FIL,N,L
VAR I%,J%
VAR SIZE%=LEN(FIL)
FOR I%=0 TO N-1
VAR TMP#=0
FOR J%=0 TO L-1
TMP#=TMP#+IN[(I%-J%+SIZE%) MOD SIZE%]*FIL[(J%+SIZE%)MOD SIZE%]
NEXT J%
O[I%]=TMP#
NEXT I%
END
'IFFTで計算
DEF FIR1 O,IN,FIL
FILL FFTJ#,0:FILL CONVOLJ#,0 '虚部を0で初期化
IFFT FFTR#,FFTJ#,IN,FFTJ#
IFFT CONVOLR#,CONVOLJ#,FIL,CONVOLJ#
'要素ごとに乗算
COPY T#,FFTJ#
ARYOP 2,FFTJ#,T#,CONVOLR#
ARYOP 4,FFTJ#,FFTR#,CONVOLJ#,FFTJ#
ARYOP 2,FFTR#,FFTR#,CONVOLR#
ARYOP 2,T#,T#,CONVOLJ#
ARYOP 1,FFTR#,FFTR#,T#
FFT O,FFTJ#,FFTR#,FFTJ#
END
'入力,フィルタ初期化
FILL SIGNAL#,79,N%>>1,N%>>1
GAUSS FILTER#,L%
'フィルタ計算
FIR0 BLURED0#,SIGNAL#,FILTER#,N%,L%
FIR1 BLURED1#,SIGNAL#,FILTER#
VAR I%
'描画
FOR I%=1 TO 399
GLINE I%-1,79-ROUND(SIGNAL#[I%-1]),I%,79-ROUND(SIGNAL#[I%])
GLINE I%-1,159-ROUND(BLURED0#[I%-1]),I%,159-ROUND(BLURED0#[I%])
GLINE I%-1,239-ROUND(BLURED1#[I%-1]),I%,239-ROUND(BLURED1#[I%])
NEXT I%
GPUTCHR 0,32,"入力",2,2
GPUTCHR 0,112,"出力(愚直)",2,2
GPUTCHR 0,192,"出力(IFFT)",2,2
WAIT 1E5