NFFTライブラリの使い方
はじめに
この記事では,C言語ライブラリNFFTの使用方法について説明します.
NFFTとは
まずは,とても簡単にNFFTについて説明します.
離散フーリエ変換
のノード
フーリエ係数
行列で書くと,
となり,NFFTとは,巨大な疎行列
通常のFFTは,ノード
計算量
1次元NFFTの計算量は,
です. ここで,
NFFTライブラリ
NFFTのC言語ライブラリの使い方について説明します.
インストール
ここの手順通りにインストールしましょう.
(注意) 事前にFFTWをインストールしておく必要があります.
- ダウンロードし,解凍後,ディレクトリに入る.
wget https://www-user.tu-chemnitz.de/~potts/nfft/download/nfft-3.5.2.tar.gz
tar -zxf nfft-3.5.2.tar.gz
cd nfft-3.5.2
- コンパイルする.
./configure --enable-all --enable-openmp && make
- インストール
sudo make install
使い方
簡単な例を示します.
今回は, コサイン
を,そのフーリエ級数
から求める,コードを示します.
ノード
#include <complex.h>
#include <nfft3.h>
int main(void)
{
nfft_plan my_plan;
int N = 4; // 波数の個数
int M = 32; // ノードxの個数
// planの初期化
nfft_init_1d(&my_plan, N, M);
// ランダムにxの値を決めてくれる関数
nfft_vrand_shifted_unit_double(my_plan.x, my_plan.M_total);
// 窓関数の計算
if (my_plan.flags & PRE_ONE_PSI)
nfft_precompute_one_psi(&my_plan);
// フーリエ級数
// 今回はcos(2*pi*x)のフーリエ変換を行う
for (int i = 0; i < my_plan.N_total; i++)
{
my_plan.f_hat[i] = 0;
}
my_plan.f_hat[my_plan.N_total / 2 - 1] = 0.5; // 波数の入れ方に注意
my_plan.f_hat[my_plan.N_total / 2 + 1] = 0.5; // 波数の入れ方に注意
// NFFTの実行
nfft_trafo(&my_plan);
// planの終了
nfft_finalize(&my_plan);
return 0;
}
1つずつ説明します.
宣言
まずは,必要な変数を宣言します.
nfft_plan my_plan;
int N = 4; // 波数の個数
int M = 32; // ノードxの個数
-
nfft_plan
は,FFTWのときと同じようなplanの宣言です. このplan変数に,NFFTの実行に必要なものをすべて詰め込んでいきます. -
N
は波数の個数です.N=4
なので, となります.k=-2, -1, 0, 1 -
M
はノード の個数です. ノードx は以下で設定します.x
初期化
プランを初期化します.
// planの初期化
nfft_init_1d(&my_plan, N, M);
プランの初期化をしています.
構造体nfft_plan型のmy_planのメンバには,
my_plan.N_total | ノード |
---|---|
my_plan.M_total | フーリエ波数 |
my_plan.x | ノード |
my_plan.f_hat | フーリエ級数 |
my_plan.f | 求めたい関数 |
などがいます.
ノードを決める
ノード
これは,
// ランダムにxの値を決めてくれる関数
nfft_vrand_shifted_unit_double(my_plan.x, my_plan.M_total);
今回は,NFFTライブラリが提供する,ランダムに格納してくれる関数nfft_vrand_shifted_unit_double
を使います.
窓関数の計算
今回理論の説明で端折ってしまいましたが,NFFTはフーリエ変換を窓関数の和で近似します.
そのため,窓関数を決め,あらかじめ計算するというステップが入ります.
// 窓関数の計算
if (my_plan.flags & PRE_ONE_PSI)
nfft_precompute_one_psi(&my_plan);
今回は,nfft_precompute_one_psi
という関数を使って,計算します.
窓関数の詳細な説明や設定は,記事を分けようと思います.
フーリエ級数の計算
フーリエ級数の計算をします.
// フーリエ級数
// 今回はcos(2*pi*x)のフーリエ変換を行う
for (int i = 0; i < my_plan.N_total; i++)
{
my_plan.f_hat[i] = 0;
}
my_plan.f_hat[my_plan.N_total / 2 - 1] = 0.5; // 波数の入れ方に注意
my_plan.f_hat[my_plan.N_total / 2 + 1] = 0.5; // 波数の入れ方に注意
今回はコサインなので簡単です.
NFFTの実行
NFFTを実行しましょう.
// NFFTの実行
nfft_trafo(&my_plan);
-
nfft_trafo
でNFFTを実行します. -
my_plan.f
に実行結果が格納されます.
また,符号が逆の変換,
を求めるときは, nfft_adjoint
を使います.
終了処理
最後にプランを破棄して終了です.
// planの終了
nfft_finalize(&my_plan);
おわりに
今回は,NFFTを実行するC言語ライブラリNFFTの説明をしました.
簡単な使用例にとどめましたが,これ以外にも,
- 逆フーリエ変換
- 2次元以上の高次元フーリエ変換
- 高速サイン・コサイン変換(NFCT,NFST)
- 球面上の変換(球面調和関数展開)NSFST
など,様々な機能があります.これらについても今後記事にしていこうと思います.
Discussion