Задача приведения комплекса STL <double>к fftw_complex - PullRequest
14 голосов
/ 18 ноября 2010

В руководстве FFTW сказано , что его тип fftw_complex является бит-совместимым с классом std::complex<double> в STL. Но это не работает для меня:

#include <complex>
#include <fftw3.h>
int main()
{
   std::complex<double> x(1,0);
   fftw_complex fx;
   fx = reinterpret_cast<fftw_complex>(x);
}

Это дает мне ошибку:

error: invalid cast from type ‘std::complex<double>’ to type ‘double [2]’

Что я делаю не так?

Ответы [ 3 ]

22 голосов
/ 02 декабря 2012

Идея совместимости битов сложных типов fftw_complex и C99 и C ++ заключается не в том, что их легко создавать друг из друга, а в том, что все функции в FFTW, которые переносят указатели на fftw_complex, могут также указывать на c ++ std :: complex,Поэтому наилучшим подходом, вероятно, является использование std :: complex <> во всей программе и преобразование указателей в эти значения только при вызове функций FFTW:

std::vector<std::complex<double> > a1, a2;
....
....
fftw_plan_dft(N, reinterpret_cast<fftw_complex*>(&a1[0]),
                 reinterpret_cast<fftw_complex*>(&a2[0]),
                 FFTW_FORWARD, FFTW_ESTIMATE);
....
8 голосов
/ 18 ноября 2010

Перепишите ваш код следующим образом:

#include <complex>
#include <fftw3.h>
int main()
{
   std::complex<double> x(1,0);
   fftw_complex fx;
   memcpy( &fx, &x, sizeof( fftw_complex ) );
}

Каждый используемый мной компилятор оптимизирует memcpy, потому что он копирует фиксированный, то есть во время компиляции, объем данных.

Это позволяет избежать проблем с наложением указателей .

Редактировать: Вы также можете избежать проблем с наложением псевдонимов, используя объединение следующим образом:

#include <complex>
#include <fftw3.h>
int main()
{
   union stdfftw
   {
       std::complex< double > stdc;
       fftw_complex           fftw;
   };
   std::complex<double> x(1,0);
   stdfftw u;
   u.stdc = x;
   fftw_complex fx = u.fftw;
}

Хотя строго эти правила C99 (Не уверен в C ++) нарушены, так как чтение от другого члена объединения к написанному тоже не определено.Это работает на большинстве компиляторов, хотя.Лично я предпочитаю мой оригинальный метод.

6 голосов
/ 18 ноября 2010

reinterpret_cast работает только для указателей и ссылок. Так что вам нужно сделать это:

#include <complex>
#include <fftw3.h>
int main()
{
   std::complex<double> x(1,0);
   fftw_complex fx(*reinterpret_cast<fftw_complex*>(&x));
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...