実装を始める [任意点数のFFT]
一通りアルゴリズムの整理ができてそれをどう割り振るかも一応決めた。
ということで実装を始めよう。ここまでくれば実装はするっ、とできる、はず。
ところで実装はもちろんObjective-Cでやる。
まあ、普通あまりこういった数値計算の、しかも効率を気にした実装をObjective-Cなんていう高水準の、ゆるい言語で実装するというのはないだろう。
でも、書いた式の思想というか意思(数式にはそういうものがあるというのはわかってもらえると思う)をそのまま書き下せるというのが一番望ましい、と言う意味でMathematicaが一番だけどObjective-Cはそれに次ぐ。僕にとって一番自然な実装方法。
実装
前節で書いたフローをObjective-Cのクラスとして実装する。 今回は、前も書いたけど- Kooley-TukeyのFFT(N=2n)
- Chirp z変換(Nは任意)
- 混合基数(Nは素数以外)
- 定義式のままのDFT(Nは任意)
つまりクラスの入り口はひとつだけで、Nの値によって実際に計算を行うクラスを内部で振り分けるような実装にする必要がある。
もちろんDFTを使うときに自分で振り分けてもいい。でもそれはあまりObjective-C/Cocoaのスタイルではない。なぜなら、
- 計算とその使い方の実装がソースの上で離れてしまう
- 使う側の負担を増やすことになって親切ではない
どうせ自分しか使わないのだからいいじゃん、という話もあるが1ヶ月後の自分は他人であるということを今のうちに認識しておいた方がいい。僕はこのせいで何度もなんども、本当に何度も無駄な時間を消費した。1ヶ月どころか一晩たった自分が他人であることもよくあった。
まあ、それはいいとして実装を考えよう。complex.hを読み込んだfftwと互換をとりたいので正規化係数はかけずにそのままにしておく(Chirp zでまた悩みそうだけど)。
また、データは上書き(in-place)にする。fftwは別の出力用の配列を用意するのがデフォルトだけど、今回まとめたアルゴリズムではバッファがいっぱい必要になるのと、スペックル計算にしか使わなくてもとのデータを残しても使い道がないのでこうしておく。out-of-placeにするには入力データをコピーしてから実行すればいいのであまり気にしないことにする。
とりあえず、今回のFFTのクラス接頭辞をArbitrary Size FFTをとってASとしよう。実装を始める前にいつもこの接頭辞をなににするかで結構悩む。objective-Cにもname spaceが欲しいな。
「なんちゃってクラスクラスタ」
クラスクラスタとその実装
クラスクラスタはCocoaのとくにFoundation frameworkにはいっぱい出てくる。文字列を扱うNSStringはその典型で、NSStringのインスタンスを作っても実際にできるのはそのサブクラスのインスタンスである。NSStringそのものは実質的に抽象クラス(C++のvertualみたいに、積極的に抽象クラスとして指定するような表現法はObjective-Cに言語仕様としては存在しないけど)になっている。その用途や期待される動作ごとにそれに適した具象クラスのインスタンスを作るようにしたもので、いろいろな使われ方をする文字列のようなオブジェクトでは
- ひとつに詰め込むとクラスが大きくなりすぎる
- 使う側に煩雑な使い分けを強要しない
クラスクラスタに関してはこの記事がわかりやすい。
使うのは簡単になっているけど、クラスクラスタを実装するのは非常に大変。 例えばNSStringの場合、
- allocメソッドではNSPlaceholderStringというシングルトンオブジェクトを返す
- init...メソッドで具体的なサブクラスを返す
シングルトンとはアプリにひとつしか存在しないオブジェクトで、複数回インスタンスを作っても同じものが返ってくるようになっている場合が多い。シングルトンもここにわかりやすい説明がある。またAppleのガイドにも詳しく書かれている。
NSStringなどのallocでシングルトンを返すのは単にパフォーマンス上の問題からで、init...で実際のオブジェクトを生成するのでそれまでなるべく何もしないですますためである。
ところがこのシングルトンの実装が面倒。NSObjectが持っているメソッドの多くを上書きしないといけない。決まりきった書き方にはなるけど、呼ばれたメソッドの中で自分が何のクラスのインスタンスなのか意識していないと道に迷ってしまう。
まじめなクラスクラスタをちゃんと実装するにはこの解説が詳しい。
2009-09-17 21:56
nice!(0)
コメント(0)
トラックバック(0)
コメント 0