Как правильно использовать kissFFT с вектором С++?

Я хочу использовать kissFFT в проекте C++ с std::vector, чтобы легко обрабатывать сигнал произвольной длины. Для этого я отредактировал этот ответ SO от автора kissFFT. я заменил

std::complex<float> x[nfft]; с

vector<std::complex<float>> x(nfft, 0.0);

и заменил вызов функции

kiss_fft(fwd,(kiss_fft_cpx*)x,(kiss_fft_cpx*)fx) с

kiss_fft(fwd,(kiss_fft_cpx*)&x[0],(kiss_fft_cpx*)&fx[0]);

Кажется, это работает очень хорошо, но правильно ли это? В папке "test" kissFFT я нашел "testcpp.cc", который, похоже, использует некоторые причудливые функции шаблона C++ (к сожалению, слишком причудливые для меня; я не смог его скомпилировать). Есть ли у моего решения недостатки?


Полный код

#include "kiss_fft.h"
#include <complex>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    const int nfft=256;
    kiss_fft_cfg fwd = kiss_fft_alloc(nfft,0,NULL,NULL);
    kiss_fft_cfg inv = kiss_fft_alloc(nfft,1,NULL,NULL);

    vector<std::complex<float>> x(nfft, 0.0);
    vector<std::complex<float>> fx(nfft, 0.0);

    x[0] = 1;
    x[1] = std::complex<float>(0,3);

    kiss_fft(fwd,(kiss_fft_cpx*)&x[0],(kiss_fft_cpx*)&fx[0]);
    for (int k=0;k<nfft;++k) {
        fx[k] = fx[k] * conj(fx[k]);
        fx[k] *= 1./nfft;
    }
    kiss_fft(inv,(kiss_fft_cpx*)&fx[0],(kiss_fft_cpx*)&x[0]);
    cout << "the circular correlation of [1, 3i, 0 0 ....] with itself = ";
    cout
        << x[0] << ","
        << x[1] << ","
        << x[2] << ","
        << x[3] << " ... " << endl;
    kiss_fft_free(fwd);
    kiss_fft_free(inv);
    return 0;
}

person Semjon Mössinger    schedule 07.09.2015    source источник


Ответы (1)


Я сам обычно использую std::vector<kiss_fft_cpx>, но в остальном мой код почти такой же, как у вас. (Ну, kiss_fft_alloc и kiss_fft_free идут в ctor/dtor, чтобы избежать утечек памяти, но это вопрос стиля.)

Чуть дальше fx[k] * conj(fx[k]) — типичное математическое выражение. Более эффективно использовать fx[k].norm().

person MSalters    schedule 07.09.2015
comment
Спасибо. А вот первый пассаж вашего ответа я так и не понял. Я пытаюсь объяснить, что я получил до сих пор: kissFFT возвращает вектор kiss_fft_cpx, но в моем примере он получает вектор std::complex. Теоретически это может привести к утечке памяти, но поскольку kiss_fft_alloc и kiss_fft_free вызывают конструктор/деструктор чего-либо (std::complex ???), на практике проблем не возникнет. - person Semjon Mössinger; 08.09.2015
comment
Еще вопрос: fwd и inv держат конфигурацию. Если я использую одну конфигурацию во второй раз, будет ли она быстрее, чем в первый раз (потому что коэффициенты поворота или что-то в этом роде уже рассчитаны)? - person Semjon Mössinger; 08.09.2015
comment
@Ergodicity: вы, вероятно, получите более быстрый ответ, просто попробовав. - person MSalters; 08.09.2015