Есть ли простой пример C++ о том, как использовать Intel MKL FFT?
Мне нужно выполнить преобразования FFT и Inverse-FFT. Входными данными будут вектор и матрицы double. В идеале выход должен быть массивом std:: complex, но я могу жить с double _Complex.
Я не нашел простого примера, все примеры Intel делают много вещей сразу без достаточного количества комментариев.
Мне просто нужен простой пример в C++, принимающий вектор (или матрицу) double в качестве ввода и вывода результата FFT-преобразования (в идеале с std:: complex).
1 ответов
Я закончил тестирование нескольких вещей, и я, наконец, закончил с этими тремя функциями, которые делают то, что я хочу, и что я рассмотрел простые примеры.
я протестировал его против некоторых входов, и у меня были хорошие результаты. Но я не проводил тщательного тестирования.
//Note after each operation status should be 0 on success
std::vector<std::complex<float>> fft_complex(std::vector<std::complex<float>>& in){
std::vector<std::complex<float>> out(in.size());
DFTI_DESCRIPTOR_HANDLE descriptor;
MKL_LONG status;
status = DftiCreateDescriptor(&descriptor, DFTI_SINGLE, DFTI_COMPLEX, 1, in.size()); //Specify size and precision
status = DftiSetValue(descriptor, DFTI_PLACEMENT, DFTI_NOT_INPLACE); //Out of place FFT
status = DftiCommitDescriptor(descriptor); //Finalize the descriptor
status = DftiComputeForward(descriptor, in.data(), out.data()); //Compute the Forward FFT
status = DftiFreeDescriptor(&descriptor); //Free the descriptor
return out;
}
std::vector<std::complex<float>> fft_real(std::vector<float>& in_real){
std::vector<std::complex<float>> in(in_real.size());
std::copy(in_real.begin(), in_real.end(), in.begin());
return fft_complex(in);
}
std::vector<float> ifft(std::vector<std::complex<float>>& in){
std::vector<std::complex<float>> out(in.size());
DFTI_DESCRIPTOR_HANDLE descriptor;
MKL_LONG status;
status = DftiCreateDescriptor(&descriptor, DFTI_SINGLE, DFTI_COMPLEX, 1, in.size()); //Specify size and precision
status = DftiSetValue(descriptor, DFTI_PLACEMENT, DFTI_NOT_INPLACE); //Out of place FFT
status = DftiSetValue(descriptor, DFTI_BACKWARD_SCALE, 1.0f / in.size()); //Scale down the output
status = DftiCommitDescriptor(descriptor); //Finalize the descriptor
status = DftiComputeBackward(descriptor, in.data(), out.data()); //Compute the Forward FFT
status = DftiFreeDescriptor(&descriptor); //Free the descriptor
std::vector<float> output(out.size());
for(std::size_t i = 0; i < out.size(); ++i){
output[i] = out[i].real();
}
return output;
}