问题是将STL复杂<double>转换为fftw_complex </double>

时间:2010-11-18 11:48:32

标签: c++ fftw complex-numbers reinterpret-cast

FFTW手册says,其fftw_complex类型与STL中的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]’

我做错了什么?

3 个答案:

答案 0 :(得分:22)

fftw_complex和C99和C ++复杂类型的位兼容性背后的想法并不是它们可以很容易地相互创建,但FFTW中指向fftw_complex的所有函数也可以指向c ++ std :: complex 。因此,最好的方法可能是使用std :: complex&lt;&gt;在整个程序中,只有在调用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);
....

答案 1 :(得分:8)

重写您的代码,如下所示:

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

我使用的每个编译器都会优化memcpy,因为它正在复制一个固定的,即在编译时,数据量。

这可以避免pointer aliasing issues

编辑:您还可以使用联合避免严格的别名问题,如下所示:

#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 ++)是破坏的,因为从一个联盟的另一个成员读取也是未定义的。它适用于大多数编译器。我个人更喜欢我原来的方法。

答案 2 :(得分:6)

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具有复制构造函数。为避免严格别名问题,首选Goz's solution