C言語でのローリング中央値アルゴリズム 質問する

C言語でのローリング中央値アルゴリズム 質問する

私は現在、C でローリング メディアン フィルター (ローリング平均値フィルターに類似) を実装するアルゴリズムに取り組んでいます。文献を調べたところ、それを実行するには 2 つのかなり効率的な方法があるようです。1 つ目は、初期値ウィンドウをソートし、バイナリ検索を実行して各反復で新しい値を挿入し、既存の値を削除する方法です。

2 番目 (Hardle および Steiger、1995、JRSS-C、アルゴリズム 296 より) は、両端にヒープ構造を構築します。一方の端に最大ヒープ、もう一方の端に最小ヒープ、中央に中央値があります。これにより、O(n log n) ではなく線形時間のアルゴリズムが生成されます。

問題は次の通りです。前者の実装は可能ですが、何百万もの時系列で実行する必要があるため、効率が非常に重要です。後者は実装が非常に難しいことが分かっています。R の統計パッケージのコードの Trunmed.c ファイルでコードを見つけましたが、解読不能です。

線形時間ローリング中央値アルゴリズムの適切に記述された C 実装を知っている人はいますか?

編集: Trunmed.c コードへのリンクhttp://google.com/codesearch/p?hl=en&sa=N&cd=1&ct=rc#mYw3h_Lb_e0/R-2.2.0/src/library/stats/src/Trunmed.c

ベストアンサー1

私も同じようなものをスタンドアロンのC++クラス/Cサブルーチンで欲しかったので、 Rをsrc/library/stats/src/Trunmed.c何度か見てきました。これは実際には2つの実装が1つになっていることに注意してください。src/library/stats/man/runmed.Rdヘルプファイルのソースを参照してください。

\details{
  Apart from the end values, the result \code{y = runmed(x, k)} simply has
  \code{y[j] = median(x[(j-k2):(j+k2)])} (k = 2*k2+1), computed very
  efficiently.

  The two algorithms are internally entirely different:
  \describe{
    \item{"Turlach"}{is the Härdle-Steiger
      algorithm (see Ref.) as implemented by Berwin Turlach.
      A tree algorithm is used, ensuring performance \eqn{O(n \log
        k)}{O(n * log(k))} where \code{n <- length(x)} which is
      asymptotically optimal.}
    \item{"Stuetzle"}{is the (older) Stuetzle-Friedman implementation
      which makes use of median \emph{updating} when one observation
      enters and one leaves the smoothing window.  While this performs as
      \eqn{O(n \times k)}{O(n * k)} which is slower asymptotically, it is
      considerably faster for small \eqn{k} or \eqn{n}.}
  }
}

これをもっと独立した形で再利用するのを見るのはいいことです。ボランティアしていただけますか? R の部分についてはお手伝いできます。

編集1: 上記のTrumped.cの古いバージョンへのリンクの他に、現在のSVNコピーがあります。

編集2: ライアン・ティブシラニはCとFortranのコードをいくつか公開しています高速中央値ビニングこれはウィンドウアプローチの適切な出発点となる可能性があります。

おすすめ記事