为什么FFTW输入非零,输出返回全零(C ++)

时间:2015-10-07 19:09:42

标签: c++ fftw

好的,所以我一直在处理以下问题一段时间,似乎无法得出答案。简而言之,我正在为雷达信号实施层析成像,并且似乎无法通过FFTW为我提供除零之外的输出。我正在通过C ++实现并使用FFTW3库。

现在的输入是场景原点的模拟点散射体,其具有所有真实场景的相位响应(参见rxphase变量)。由于使用的带宽等,滤波后的接收信号的IFFT应该相当大(我还没有缩放),但每个脉冲都得零。

摘自我的代码:

void ifftshift(std::vector<phdata> &argin, std::size_t count){
  int k = 0;
  int c = (int)floor((float)count/2);

  if (count % 2 == 0)
  {
    for (k=0; k<c;k++)
    {
      complex<double> tmp = argin[k];
      argin[k] = argin[k+c];
      argin[k+c] = tmp;
    }
  }
  else
  {
    complex<double> tmp = argin[count-1];
    for (k=c-1; k>=0; k--)
    {
      argin[c+k+1] = argin[k];
      argin[k] = argin[c+k];
    }
    argin[c] = tmp;
  }
};

void main(){

  std::vector<complex<double> > filteredData;
  // Number of pulses across the aperture
  std::int pulses = 11;
  // Define the frequency vector
  std::vector<double> freq;
  std::double freqmin = 9 * pow(10,9);
  std::double freqmax = 11 * pow(10,9);
  std::vector<complex<double> > outData;
  std::vector<complex<double> > rxphase;

  for  (int i = 0; i<64; i++)
  {
    freq.push_back(freqmin + (((freqmax-freqmin)/64)*i));
  }

  // Create a (samples X pulses) array of complex doubles
  rxphase.assign(64, std::vector<complex<double> > (11, {1,0}) );

  fftw_complex *in, *out;
  fftw_plan plan;

  in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * image.Nfft );
  out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * image.Nfft );
  plan = fftw_plan_dft_1d(image.Nfft, in, out, FFTW_BACKWARD, FFTW_MEASURE);

  // iterate through pulses to back project across the aperture
  for ( int i=0; i<=pulses; i++ )
  {
    // Reset vectors for each pulse
    filteredData.clear();
    outData.clear();

    for ( int ii=0; ii<freq.size(); ii++ )
    {
      // Apply simple ramp filter
      filteredData.push_back(freq[ii]*rxphase[ii][i]);
    }

    // Shift the data to put the center frequency at DC position (zero index)
    ifftshift(filteredData, filteredData.size());

    for (int ii=0; ii<filteredData.size(); ii++)
    {
      std::cout << filteredData[ii] ;
    }
    std::cout << std::endl;
    // filteredData is what I expect it to be.

    // Recast the vector to the type needed for FFTW and compute FFT
    in = reinterpret_cast<fftw_complex*>(&filteredData[0]);

    for (int ii=0; ii<filteredData.size(); ii++)
    {
      std::cout << "(" << (in[ii])[0] << "," << (in[ii])[1] << ");";
    }
    std::cout << std::endl;
    // values for in are the same as for filteredData, as expected.

    fftw_execute(plan);

    for (int ii=0; ii<filteredData.size(); ii++)
    {
      std::cout << "(" << (out[ii])[0] << "," << (out[ii])[1] << ");";
    }
    std::cout << std::endl;
    // The values for out are all (0,0)
  }

  fftw_destroy_plan(plan);
  //fftw_free(in); error here
  //fftw_free(out); error here
};

任何帮助将不胜感激。

编辑:代码应该更完整一些。

2 个答案:

答案 0 :(得分:2)

混乱可能源于行

in = reinterpret_cast<fftw_complex*>(&filteredData[0]);

虽然这会将局部变量in更新为指向存储数据的内存区域(filteredData向量的存储缓冲区),但它不会更新由内部保留的指针。 plan。因此,FFTW知道并用作输入缓冲区的内存区域仍然是您最初使用

分配的内存区域
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * image.Nfft );

并指定为

的参数
fftw_plan_dft_1d(image.Nfft, in, out, FFTW_BACKWARD, FFTW_MEASURE);
//                           ^^

请注意,在整个程序中,此内存区域仍未初始化(可能恰好为零)。

您应该使用:

直接写入in输入缓冲区
for ( int ii=0; ii<freq.size(); ii++ )
{
    // Apply simple ramp filter
    std::complex<double> value = freq[ii]*rxphase[ii][i];
    in[ii][0] = value.real();
    in[ii][1] = value.imag();
}

毋庸置疑,在这种情况下,in = reinterpret_cast<fftw_complex*>(&filteredData[0])行也应该删除。

或者,如果您使用的编译器中fftw_complexstd::complex<double>是二进制兼容的(请参阅FFTW documentation of Complex numbers type),您可能更愿意:

std::complex<double>* filteredData = reinterpret_cast<std::complex<double>*>(in);
for ( int ii=0; ii<freq.size(); ii++ )
{
    // Apply simple ramp filter
    filteredData[ii] = freq[ii]*rxphase[ii][i];
}

答案 1 :(得分:2)

要快速而肮脏地思考这个问题,请先使用fftw_plan 创建fftw_plan_dft_1d ,将有效输入数组的内容修改为fftw_plan_dft_1d正如SleuthEye所提到的,然后调用fftw_execute