Problem casting STL complex to fftw_complex

前端 未结 3 1583
鱼传尺愫
鱼传尺愫 2020-12-28 08:25

The FFTW manual says that its fftw_complex type is bit compatible to std::complex class in STL. But that doesn\'t work for me:

<
相关标签:
3条回答
  • 2020-12-28 08:54

    Re-write your code as follows:

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

    Every compiler I've used will optimise out the memcpy because it is copying a fixed, ie at compile time, amount of data.

    This avoids pointer aliasing issues.

    Edit: You can also avoid strict aliasing issues using a union as follows:

    #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;
    }
    

    Though strictly this C99 rules (Not sure about C++) are broken as reading from a different member of a union to the one written too is undefined. It works on most compilers though. Personally I prefer my original method.

    0 讨论(0)
  • 2020-12-28 09:03

    The idea behind bit-compatibility of fftw_complex and C99 and C++ complex types is not that they can be easily created from one another, but that all functions in FFTW that take pointers to fftw_complex can also take pointers to c++ std::complex. Therefore the best approach is probably to use std::complex<> throughout your program and only convert pointers to these values when calling FFTW functions:

    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);
    ....
    
    0 讨论(0)
  • 2020-12-28 09:04

    reinterpret_cast only works for pointers and references. So you'd have to do this:

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

    This assumes that fftw_complex has a copy constructor. To avoid problems with strict aliasing, Goz's solution should be preferred.

    0 讨论(0)
提交回复
热议问题