Алгоритм DFT и свертка. что случилось? - PullRequest
1 голос
/ 22 ноября 2010

<pre></p> <pre><code>#include <vector> using std::vector; #include <complex> using std::complex; using std::polar; typedef complex<double> Complex; #define Pi 3.14159265358979323846 // direct Fourier transform vector<Complex> dF( const vector<Complex>& in ) { const int N = in.size(); vector<Complex> out( N ); for (int k = 0; k < N; k++) { out[k] = Complex( 0.0, 0.0 ); for (int n = 0; n < N; n++) { out[k] += in[n] * polar<double>( 1.0, - 2 * Pi * k * n / N ); } } return out; } // inverse Fourier transform vector<Complex> iF( const vector<Complex>& in ) { const int N = in.size(); vector<Complex> out( N ); for (int k = 0; k < N; k++) { out[k] = Complex( 0.0, 0.0 ); for (int n = 0; n < N; n++) { out[k] += in[n] * polar<double>(1, 2 * Pi * k * n / N ); } out[k] *= Complex( 1.0 / N , 0.0 ); } return out; }

Кто может сказать, что не так ???

Может быть, я не понимаю детали реализации этогоалгоритм ... но я не могу его найти)))

также мне нужно вычислить свертку.

Но я не могу найти пример теста.

ОБНОВЛЕНИЕ

<pre> // convolution. I suppose that x0.size == x1.size vector convolution( const vector& x0, const vector& x1) { const int N = x0.size();</p> <pre><code>vector<Complex> tmp( N ); for ( int i = 0; i < N; i++ ) { tmp[i] = x0[i] * x1[i]; } return iF( tmp );

}

Ответы [ 3 ]

3 голосов
/ 22 ноября 2010

Я действительно не знаю точно, о чем вы спрашиваете, но ваши алгоритмы DFT и IDFT выглядят правильно для меня.Свертка может быть выполнена с использованием DFT и IDFT с использованием теоремы о круговой свертке , которая в основном утверждает, что f**g = IDFT(DFT(f) * DFT(g)), где ** - это круговая свертка, а * - простое умножение.

Для вычисления линейной свертки (некруговой) с использованием ДПФ необходимо заполнить нулями каждый из входов, чтобы циклическое свертывание имело место только для сэмплов с нулевым значением и не влияло на выход.Каждая входная последовательность должна быть дополнена нулями до длины N >= L+M-1, где L и M - длины входных последовательностей.Затем вы выполняете циклическую свертку, как показано выше, и первые L+M-1 выборки являются выходными данными линейной свертки (выборок после этого должно быть ноль).

Примечание: Выполнение свертки с DFT и IDFTалгоритмы, которые вы показали, намного более неэффективны, чем просто вычисление их напрямую.Преимущество достигается только при использовании алгоритмов FFT и IFFT (O (NlogN)) вместо DFT и IDFT (O (N ^ 2)).

1 голос
/ 22 ноября 2010

Проверьте FFTW библиотека "для вычисления дискретного преобразования Фурье (DFT)" и его C # обертка ;) Может быть это тоже;)

Удачи!

0 голосов
/ 22 ноября 2010

Преобразования выглядят нормально, но в программе нет ничего, что делает свертку.

ОБНОВЛЕНИЕ: код свертки должен сначала преобразовать входные данные перед поэлементным умножением.

...