FIRフィルタの境界条件

昨日のTest Firstの話。Test Firstそのものと境界条件は必ずしも抱合関係にないと思いますが、とにかく少し考えて見ます。
境界条件とは、つまりループや条件判定の境界で動作がきわどくなるからきわどい条件を最初から用意しちゃえってことです。たとえば、データがNのときに挙動が変わるのがわかっているアルゴリズム*1にたいして、

  • N-1
  • N
  • N+1

を与えてやろうってわけです。「Nより大きい」なんて判定は結構間違いがちですからこれが有用なのはわかります*2
さて、FIRフィルタの場合はどうでしょうか。Nタップのフィルタを書いていて確かに気にかかる点はあります。

  • 0番目の係数はちゃんと処理できているか
  • N-1番目の係数はちゃんと処理できているか
  • まさかN番目の係数まで処理していないだろうな
  • 0番目のデータはちゃんと処理できているか
  • 1番目のデータはちゃんと処理できているか
  • N-1番目、N番目のデータはちゃんと処理できているか

また与えるデータの個数ですが、

  • 負の個数を与えるとどうなるか
  • 0個のデータを与えるとどうなるか
  • 32767個のデータ、32768個のデータを与えるとどうなるか

は、いつも気にしています。正直最後の一項をチェックするのは気が重いです。組み込み信号処理ではよくあることですが、C言語では配列インデックスにsigned型を許さないなどという枷がほしいところです。
さらに

  • N自身に0を与えるとどうなるか、
  • 1ならば
  • 32767ならば
  • 32768ならばどうなるか

も、気になるところ。そしてなんといってもSIMDの場合はアライメントが問題になります。これはCコンパイラの庇護の下では問題にならないことですね。アーキテクチャがミス・アライメントSIMDを許さない*3ならば、きちんと対処する必要があります。

  • Nが並列度の整数倍ではないとき
  • データ個数が並列度の整数倍ではないとき
  • データのアドレスが並列度の整数倍ではないとき

最初と2番目のケースは当たり前に発生します。かつて自分で書いたルーチンではエラーチェックせずに、「プログラマが自分で対応すること」としていました。自分で使うときには十分対応できるのですが、しくじれば例外が発生します。
最後のケースをエラーとするか、どうかはきわどいです。自分で書いたルーチンでは、単に例外をおこさせていました。VisualDSP++のライブラリでは、このときSISD処理に縮退しています。C言語のライブラリとしてはそれが正しそう。
そういうわけで、FIRフィルタを一本書くだけでも結構気を使うのです。Test Firstが重要だと段々思えてきました。

*1:たとえばNより大きいかどうか判定するアルゴリズム

*2:Djkstraだったかなぁ。if文にelseをつけさせるなって主張があった。ようするに条件は全部明示しろってこと

*3:C64+は許す。ただしバスバンド幅が半分になる