【问题标题】:Problem casting STL complex<double> to fftw_complex将 STL complex<double> 转换为 fftw_complex 的问题
【发布时间】:2011-05-11 23:50:48
【问题描述】:

FFTW 手册saysfftw_complex 类型与STL 中的std::complex&lt;double&gt; 类位兼容。但这对我不起作用:

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

我做错了什么?

【问题讨论】:

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


    【解决方案1】:

    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);
    ....
    

    【讨论】:

    • 迄今为止最好的方法。
    【解决方案2】:

    重写你的代码如下:

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

    【讨论】:

    • 好的,这对我有用! 3 年没有用纯 C 编码了 :) 非常感谢。
    • @galadog memcpy 有必要吗?你为什么不能这样做:std::complex&lt;double&gt; x(1,0); fftw_complex* fx = &amp;x
    • 复数数组怎么样?
    【解决方案3】:

    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

    【讨论】:

    • 您在上面的操作违反了严格的别名规则,应该避免。 GCC 会警告你这样做,如果你打开了严格的别名,它可能会中断。
    • @Goz:你是对的。我添加了一条警告并参考了您的答案。
    • 也适用于参考:fftw_complex fx(reinterpret_cast&lt;fftw_complex&amp;&gt;(x));
    猜你喜欢
    • 2014-03-23
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多