Вопрос

Руководство FFTW говорит это его fftw_complex тип немного совместим с std::complex<double> класс в СТЛ. Но это не работает для меня:

#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]’

Что я делаю неправильно?

Это было полезно?

Решение

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

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

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

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

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

#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 ++) нарушаются как чтение от другого члена союза к одному написанному тоже не определено. Это работает на большинстве компиляторов, хотя. Лично я предпочитаю свой оригинальный метод.

Другие советы

Идея совместимости битовой совместимости FFTW_Complex и C99 и C ++ сложных типов, не то, что их можно легко создавать друг от друга, но что все функции в FFTW, которые принимают указатели на FFTW_COMPLEX, также могут принимать указатели на C ++ STD :: комплекс. Поэтому лучший подход, вероятно, используется 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);
....

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 Имеет копию конструктор. Чтобы избежать проблем со строгим псевдонимом, Решение Госа должно быть предпочтительным.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top