The FFTW manual says that its fftw_complex
type is bit compatible to std::complex<double>
class in STL. But that doesn't work for me:
#include <complex>
#include <fftw3.h>
int main()
{
std::complex<double> x(1,0);
fftw_complex fx;
fx = reinterpret_cast<fftw_complex>(x);
}
This gives me an error:
error: invalid cast from type ‘std::complex<double>’ to type ‘double [2]’
What am I doing wrong?
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);
....
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With