Question

Le FFTW manuel dit son type de fftw_complex est peu compatible avec std::complex<double> classe STL. Mais cela ne fonctionne pas pour moi:

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

Cela me donne une erreur:

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

Qu'est-ce que je fais mal?

Était-ce utile?

La solution

Re-écrire votre code comme suit:

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

Chaque compilateur que je l'ai utilisé optimisera le memcpy parce qu'il est la copie d'un fixe, soit au moment de la compilation, la quantité de données.

Cela évite pointeur problèmes aliasing .

Modifier Vous pouvez également éviter des problèmes sévères d'aliasing en utilisant une union comme suit:

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

Bien que strictement ces règles de C99 (ne suis pas sûr C ++) sont brisés comme la lecture d'un autre membre d'un syndicat à celui écrit aussi est indéfini. Il fonctionne sur la plupart des compilateurs bien. Personnellement, je préfère ma méthode originale.

Autres conseils

L'idée derrière bit compatibilité des fftw_complex et C99 et C ++ types complexes ne sont pas qu'ils peuvent être facilement créés les uns des autres, mais que toutes les fonctions de FFTW qui prennent des pointeurs vers fftw_complex peut également prendre des pointeurs vers c ++ std :: complexe . Par conséquent, la meilleure approche est probablement d'utiliser std :: complexe <> tout au long de votre programme et convertir uniquement des pointeurs vers ces valeurs lors de l'appel des fonctions de 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 ne fonctionne que pour les pointeurs et les références. Il faudrait donc faire ceci:

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

Cela suppose que fftw_complex a un constructeur de copie. Pour éviter les problèmes avec aliasing strict, la solution de Goz devrait être préféré.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top