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

gal*_*dog 14 c++ complex-numbers fftw reinterpret-cast

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);
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个错误:

error: invalid cast from type ‘std::complex<double>’ to type ‘double [2]’
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

小智 22

背后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);
....
Run Code Online (Sandbox Code Playgroud)


Goz*_*Goz 8

重写您的代码如下:

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

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

这可以避免指针别名问题.

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

虽然严格来说这个C99规则(不确定C++)是破坏的,因为从一个联盟的另一个成员读取也是未定义的.它适用于大多数编译器.我个人更喜欢我原来的方法.


Bjö*_*lex 6

reinterpret_cast仅适用于指针和引用.所以你必须这样做:

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

这假设fftw_complex有一个复制构造函数.为了避免严格混叠的问题,Goz的解决方案应该是首选.

  • 你上面做的是打破严格的别名规则,应该避免.GCC会警告你这样做,如果你打开了严格的别名,它可能会破坏. (2认同)
  • 也适用于参考:`fftw_complex fx(reinterpret_cast <fftw_complex&>(x));` (2认同)