8

Rprof を使用すると、dtt パッケージの dct が、実行速度が非常に遅い R コードの主な原因であることが明らかになりました。stats パッケージで fft に交換すると (これは同じ変換ではありませんが、計算には同じ時間がかかるはずです)、実行時間が劇的に改善されました。実際、私の Rprof 行の 3 分の 2 は以前は dct 呼び出しであり、約 600 行のうちわずか 3 行が切り替え後に fft 呼び出しでした。

dtt パッケージの dct 実装は、高速離散フーリエ変換を使用して行われていませんか? もしそうなら、それを持っているパッケージはありますか? (1 のデータを 2 倍にして、それらの fft 係数から dct の係数を抽出できることはわかっていますが、まっすぐ高速な dct の方が確実に優れており、どこかにあるはずです)。

4

3 に答える 3

12

高速 dct はないようですが、統計パッケージには fft (高速フーリエ変換) があるため、fft を使用して高速 dct を取得する方法を次に示します。

これは自己責任で使用してください。私はそれについて深刻なチェックをしていません。サイズの異なるいくつかのベクトルでチェックしたところ、パッケージ dtt の関数 dct と同じ結果が得られました。誰かが dct からの出力と比較して私を再確認したい場合は、遠慮なくそうして結果を投稿してください。

ベクトルを次の 2 倍の長さのベクトルに拡張します。ベクトルが v=(1,2,3) の場合、エントリを w=(1,2,3,3,2,1) に 2 倍にします。順序に注意してください。ベクトルが v=(1,2,4,9) の場合、エントリを w=(1,2,4,9,9,4,2,1) に 2 倍にします。

N を元のベクトルの長さとします (長さを 2 倍にする前)。

次に、.5 * fft(w)/exp(complex(imaginary=pi / 2 / N)*(seq(2*N)-1)) の最初の N 係数は、dct(v) の計算と一致する必要があります。ほとんどすべてのケースで劇的に速くなります。

速度に関する考慮事項。素因数 N の場合、高速の dct を計算するのにかかる時間は、これらの素因数のそれぞれについて低速の dct を実行するのにかかる時間に似ています。したがって、N が 2^K の場合、長さ 2 のベクトルに対して K 個の異なる低速dct変換を実行するようなものであり、非常に高速です。N が素数の場合 (最悪の場合)、速度はまったく向上しません。最大のスピードアップは、長さが 2 のべき乗であるベクトルにあります。

注: 上記の R コードは信じられないほど不親切に見えるので、何が起こっているのかを説明させてください。正しい方法で長さを 2 倍にした後、得られる fft の最初の N 個の係数はほぼ正しいものになります。ただし、係数を少し調整する必要があります。P は e^(pi * i / 2 / N) を表します。最初の係数はそのままにしておきます。2 番目の係数を P で割り、3 番目を P^2 で割り、4 番目を P^3 で割ります。次に、すべての係数を (最初の係数を含めて) 2 で割って、R が dct に使用する正規化に一致させます。 .

これは、パッケージ dtt で dct 関数を使用するのと同じ結果をもたらすはずですが、ほとんどすべての場合で劇的に高速になります。

于 2012-06-28T18:57:11.407 に答える