Domanda

Il manuale della FFTW dice quello è fftw_complex il tipo è leggermente compatibile con std::complex<double> classe in STL.Ma questo non funziona per me:

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

Questo mi dà un errore:

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

Che cosa sto facendo di sbagliato?

È stato utile?

Soluzione

Riscrivi il tuo codice come segue:

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

Ogni compilatore che ho utilizzato ottimizzerà memcpy perché sta copiando una quantità fissa di dati, ovvero in fase di compilazione.

Questo evita problemi di aliasing del puntatore.

Modificare: Puoi anche evitare problemi di aliasing rigorosi utilizzando un'unione come segue:

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

Sebbene rigorosamente queste regole C99 (non sono sicuro di C++) siano interrotte poiché anche la lettura da un membro diverso di un'unione a quella scritta non è definita.Funziona però sulla maggior parte dei compilatori.Personalmente preferisco il mio metodo originale.

Altri suggerimenti

L'idea alla base di bit-compatibilità dei fftw_complex e C99 e C ++ tipi complessi, non è che possono essere facilmente creati l'uno dall'altro, ma che tutte le funzioni in FFTW che prendono puntatori a fftw_complex può anche prendere puntatori a C ++ std :: complessa . Pertanto l'approccio migliore è probabilmente quello di usare std :: complesso <> tutto il programma e convertire solo puntatori a questi valori quando si chiamano le funzioni 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 funziona solo per i puntatori e riferimenti. Quindi dovreste fare questo:

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

Questo presuppone che fftw_complex ha un costruttore di copia. Per evitare problemi con rigorosa aliasing, la soluzione di Goz dovrebbe preferire.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top