0

FFTW を使用して係数を生成しました。元のデータを再構築したいのですが、numCoefsすべてではなく最初の係数のみを使用します。現時点では、非常に遅い以下のコードを使用しています。

for ( unsigned int i = 0; i < length; ++i )
{
    double sum = 0;
    for ( unsigned int j = 0; j < numCoefs; ++j )
    {
        sum += ( coefs[j][0] * cos( j * omega * i ) ) + ( coefs[j][1] * sin( j * omega * i ) );
    }
    data[i] = sum;
}

もっと速い方法はありますか?

4

2 に答える 2

6

はるかに簡単な解決策は、不要な係数をゼロにしてから、FFTW で IFFT を実行することです。これは、上記のように IDFT を実行するよりもはるかに効率的です。

この種のことを行うと、時間領域でいくつかのアーティファクトが発生する可能性があることに注意してください-周波数領域でステップ関数を効果的に乗算しています。これは、時間領域でのsinc関数との畳み込みと同等です。結果として生じる時間領域での「リンギング」を減らすには、ウィンドウ関数を使用して、非ゼロ係数とゼロ係数の間の遷移を滑らかにする必要があります。

于 2011-09-29T10:42:00.307 に答える
1

あなたnumCoefsがlog(長さ)に近いかそれ以上の場合、計算の複雑さでO(n * log(n))であるIFFTは、おそらく事前に最適化されているだけでなく、高速になります。保持したい係数を除くすべてのビンをゼロにするだけで、実際の結果が必要な場合は、それらの負の周波数複素共役も保持するようにしてください。

log(length) に比べて小さい場合は、6 桁を超える精度が実際に必要ない場合は使用して、内側のループの外側で omega*i を事前に計算するなどnumCoefs、他の最適化を試すことができます (ただし、コンパイラは最適化設定が低いかオフになっていない限り、それを行ってください)。sinf()cosf()

于 2011-09-29T17:24:11.573 に答える