15

FFTW のマニュアルによると、その型はSTL のクラスfftw_complexとビット互換性があります。std::complex<double>しかし、それは私にはうまくいきません:

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

これは私にエラーを与えます:

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

私は何を間違っていますか?

4

3 に答える 3

23

fftw_complex と C99 および C++ の複合型のビット互換性の背後にある考え方は、それらが相互に簡単に作成できるということではなく、fftw_complex へのポインターを取る FFTW のすべての関数が c++ std::complex へのポインターも取ることができるということです。したがって、おそらく最善の方法は、プログラム全体で std::complex<> を使用し、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);
....
于 2012-12-01T23:32:59.383 に答える
8

次のようにコードを書き直します。

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

私が使用したすべてのコンパイラは、memcpy を最適化します。これは、コンパイル時に一定量のデータをコピーしているためです。

これにより、ポインターのエイリアシングの問題が回避されます。

編集:次のようにユニオンを使用して、厳密なエイリアシングの問題を回避することもできます。

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

厳密には、この C99 ルール (C++ については不明) は破られていますが、ユニオンの別のメンバーから書かれたものへの読み取りは定義されていないためです。ただし、ほとんどのコンパイラで動作します。個人的にはオリジナルの方法が好きです。

于 2010-11-18T11:52:24.267 に答える
6

reinterpret_castポインターと参照に対してのみ機能します。したがって、これを行う必要があります:

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

fftw_complexこれは、コピー コンストラクターがあることを前提としています。厳密なエイリアシングの問題を回避するには、Goz のソリューションを優先する必要があります。

于 2010-11-18T11:51:55.943 に答える