1

c++でfftw(自己定義のfft関数を置き換える)を学んでいます。古いコードでは、アルゴリズムは std::vector サンプル ストレージで設計されています。ドキュメントによると、キャストを使用して fftw データ型をデータ (std::vector) とやり取りします。

#include <fftw3.h>
#include <vector>
#include <iostream>
#include <complex>

using namespace std;

void main(void)
{
  std::vector< complex<double> > x(4);
  x[0] = std::complex<double>(0.0, 0.0);
  x[1] = std::complex<double>(1.0, 0.0);
  x[2] = std::complex<double>(0.0, 2.0);
  x[3] = std::complex<double>(3.0, 3.0);

  // print the vector, looks good
  for (int i=0; i<4; i++)
  {
    cout << x[i] << endl;
  }    

  // refer fftw datatype to the std::vector by casting
  fftw_complex* in = reinterpret_cast<fftw_complex*>(&x[0]);

  // print in reference, gives random numbers
  for (int i=0; i<4; i++)
  {
    cout << *in[i*2] << " " << *in[i*2+1] << endl;
  }
}

しかし、実際には正しい場所を指していないようで、代わりに乱数が表示されます。上記の質問に加えて、私の目的は 8 つの要素 (例) を持つベクトルを生成することです。最初の 4 つの要素は std::vector を参照しますが、最後の 4 つの要素は定数として初期化されます。*in ベクトルの最初のものを指し、次に別の場所で 4 つの定数値を指している可能性があるので、「in」で fftw できますか? ありがとう。

4

2 に答える 2

2

http://www.fftw.org/fftw3_doc/Complex-numbers.html#Complex-numbersで述べたように、reinterpret_cast を使用して double から fftw_complex に変換する必要があります。これは、推奨される使用法である数少ないケースの 1 つだと思います。

fftw_complex は次のように定義されていることも述べています。

typedef double fftw_complex[2];

したがって、ループを横切る正しい方法は、次のようにすることです。

for (int i=0; i<4; i++)
{
    fftw_complex* in = reinterpret_cast<fftw_complex*>(&x[i]);
    cout << (*in)[0] << " " << (*in)[1] << endl;
}

アップデート

前に行ったように in ポインターの定義を保持し、これを実行して for ループを繰り返すこともできます。

for (int i=0; i<4; i++)
{
    cout << (in[i])[0] << " " << (in[i])[1] << endl;
}
于 2013-09-18T17:00:37.630 に答える
-2

まず、reinterpret_cast を使用しないでください。これは、ひどいバグを引き起こす可能性があるためです。

2 つ目は、複素数として定義された、2 つの double を持つ構造体です。したがって、in[i*2] は、配列内の倍精度数 (i*2)*2 および (i*2)*2+1 で構成される、i*2 でインデックス付けされた COMPLEX 数にアクセスします。i==1 では実際には 2 番目ではなく 4 番目の複素数を出力し、i==2 では範囲外になり、無効なメモリ アクセス クラッシュまたはガベージ出力のいずれかが発生します。

于 2013-09-18T16:38:27.133 に答える