Pregunta

I am learning fftw (replace the self-defined fft function) in c++. In the old code, I have the algorithm designed in std::vector samples storage. According to the document, I use casting to interact the fftw datatype to my data (in 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;
  }
}

But in seems not really pointing to the right place, it shows random numbers instead. Besides above question, my purpose is to generate a vector with 8 elements (example), the first 4 element refer to the std::vector but the last four is initialized as some constant. Is that possible to have *in pointing to the first in vector and then pointing to 4 constant values somewhere else, so I can fftw "in"? Thanks.

¿Fue útil?

Solución

As said in http://www.fftw.org/fftw3_doc/Complex-numbers.html#Complex-numbers you must use reinterpret_cast to convert from double to fftw_complex. I guess this is one of the few cases that it is an adviced use.

It says too that fftw_complex is defined as:

typedef double fftw_complex[2];

so, the correct way to transverse you loop is by doing the following:

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

UPDATE

You can also keep your in pointer definition as done before and interating you for loop doing this:

for (int i=0; i<4; i++)
{
    cout << (in[i])[0] << " " << (in[i])[1] << endl;
}

Otros consejos

First, never use reinterpret_cast because that can cause awful bugs.

Second, in defined as a complex number, a structure with 2 doubles. Therefore in[i*2] would access COMPLEX number indexed by i*2, consisting of doubles number (i*2)*2 and (i*2)*2+1 in the array. At i==1 you would actually output the 4th complex number, not the 2nd one, and at i==2 you would go out of bounds, causing either an invalid memory access crash or a garbage output.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top