Frage

Das FFTW -Handbuch sagt das ist es fftw_complex Typ ist ein bisschen kompatibel für std::complex<double> Klasse in stl. Aber das funktioniert für mich nicht:

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

Dies gibt mir einen Fehler:

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

Was mache ich falsch?

War es hilfreich?

Lösung

Schreiben Sie Ihren Code wie folgt neu:

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

Jeder Compiler, den ich verwendet habe, optimiert das MemcPy, da er einen festen Kopieren, dh zur Kompilierungszeit und Datenmenge, kopiert.

Dies vermeidet Zeiger -Aliasing -Probleme.

Bearbeiten: Sie können auch strikte Aliasing -Probleme unter Verwendung einer Gewerkschaft wie folgt vermeiden:

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

Obwohl diese C99 -Regeln (nicht sicher über C ++) als Lesen von einem anderen Mitglied einer Gewerkschaft als auch geschrieben sind, ist nicht definiert. Es funktioniert jedoch bei den meisten Compilern. Persönlich bevorzuge ich meine ursprüngliche Methode.

Andere Tipps

Die Idee hinter der Bit-Kompatibilität von FFTW_Complex und C99- und C ++-komplexe Typen ist nicht, dass sie leicht voneinander erstellt werden können, sondern dass alle Funktionen in FFTW, die Zeiger auf fftw_complex bringen, auch Zeiger auf C ++ Std :: Komplex bringen können. Daher ist der beste Ansatz wahrscheinlich, std :: komplex <> während Ihres gesamten Programms zu verwenden und Zeiger nur in diese Werte zu konvertieren, wenn sie FFTW -Funktionen aufrufen:

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 funktioniert nur für Zeiger und Referenzen. Sie müssten das also tun:

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

Dies setzt das voraus fftw_complex Hat einen Kopierkonstruktor. Probleme mit striktem Aliasing zu vermeiden, Goz 'Lösung sollte bevorzugt werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top