Pregunta

El manual FFTW dice que es fftw_complex El tipo es bit compatible para std::complex<double> clase en stl. Pero eso no funciona para mí:

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

Esto me da un error:

error: invalid cast from type ‘std::complex<double>’ to type ‘double [2]’

¿Qué estoy haciendo mal?

¿Fue útil?

Solución

Reescribe tu código de la siguiente manera:

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

Cada compilador que he usado optimizará el MEMCPY porque está copiando una cantidad fija, es decir, en el momento de la compilación.

Esto evita Problemas de alias de puntero.

Editar: También puede evitar problemas estrictos de alias utilizando un sindicato de la siguiente manera:

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

Aunque estrictamente estas reglas de C99 (no estoy segura de C ++) se rompen como la lectura de un miembro diferente de un sindicato a la escrita también está indefinida. Sin embargo, funciona en la mayoría de los compiladores. Personalmente prefiero mi método original.

Otros consejos

La idea detrás de la compatibilidad de bit de los tipos complejos FFTW_COMPLEX y C99 y C ++ no es que puedan crearse fácilmente entre sí, sino que todas las funciones en FFTW que llevan punteros a FFTW_COMPLEX también pueden llevar punteros a C ++ Std :: Complex. Por lo tanto, el mejor enfoque es probablemente usar STD :: Complex <> a lo largo de su programa y solo convertir punteros a estos valores al llamar a las funciones 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);
....

reinterpret_cast Solo funciona para punteros y referencias. Entonces tendrías que hacer esto:

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

Esto supone que fftw_complex tiene un constructor de copias. Para evitar problemas con alias estricto, La solución de Goz debe ser preferido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top