程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程綜合問答 >> 變換-fftw使用的問題 頻域抽取失敗 高手請進~

變換-fftw使用的問題 頻域抽取失敗 高手請進~

編輯:編程綜合問答
fftw使用的問題 頻域抽取失敗 高手請進~

int FFTw_IFFTw_Fun2(IN dDataArray* pRRIData, IN float fmin, IN float fmax, OUT dDataArray& VLFData)
{
try
{
int nSamples = pRRIData->m_nSamples;
int N = pRRIData->m_nLen;
int Nout = floor(N/2)+1;//實數據的DFT具有 Hermitian對稱性,所以只需要計算n/2+1(向下取整)個輸出就可以了。比如對於r2c,輸入in有n個數據,輸出out有floor(n /2)+1個數據。

    fftw_complex* out1;
    fftw_complex* out2;
    double* out3;
    out1 =  (fftw_complex *)fftw_malloc(sizeof(double)*Nout * 2);
    out2 =  (fftw_complex *)fftw_malloc(sizeof(double)*Nout * 2);
    out3 =  (double *)fftw_malloc(sizeof(double)*N);

    /////////////////////////fft變換/////////////////////////////////////////////////
    fftw_plan p = fftw_plan_dft_r2c_1d(N, pRRIData->m_pData, out1,  FFTW_ESTIMATE);     
    fftw_execute(p);// 執行變換 ... 
    fftw_destroy_plan(p);

    /////////////////////////頻域抽取/////////////////////////////////////////////////
    float f1 = fmin;
    float f2 = fmax;

    float K = 0.0f;
    for (int m=0; m<Nout-1; m++)
    {
        K=m/(Nout/nSamples);
        if ((K < f1 || K > f2) || (K > (nSamples - f2) && K < (nSamples - f1)))//1/dt為一個頻率周期
        {
            out2[m][0] = 0;
            out2[m][1] = 0;
        }
        else 
        {
            out2[m][0] = out1[m][0];
            out2[m][1] = out1[m][1];
        }
    }

    //////////////////////////////////IFFT變換////////////////////////////////////////
    fftw_plan  c2cP;
    c2cP = fftw_plan_dft_c2r_1d( N, out2, out3,  FFTW_ESTIMATE);//需注意FFTW的逆變換沒有除以N,即數據正變換再反變換後是原始數據的N倍。
    fftw_execute(c2cP);
    fftw_destroy_plan(c2cP);

    VLFData.m_nLen = N;
    VLFData.m_nSamples = 2;
    VLFData.m_pData = new double[VLFData.m_nLen];
    memset(VLFData.m_pData,0,sizeof(double)*VLFData.m_nLen);

    for (int i=0; i< N; i++)
    {
        VLFData.m_pData[i] = out3[i]/N;//取實數
    }

    fftw_free(out1);
    fftw_free(out2);
    fftw_free(out3);
    TRACE(_T("int  FFTw_IFFTw_Fun2 函數返回1~"));
    return 1;
}
catch (...)
{
    TRACE(_T("int  FFTw_IFFTw_Fun2 函數catch到錯誤~"));
    return -1;
}

}

        float fmin = 0.0f;
        float fmax = 0.0033f;
        dataOutput.VLFData.Init();
        FFTw_IFFTw_Fun2(&dataOutput.RRIData, fmin, fmax, dataOutput.VLFData);

出來的波形跟原始數據波形極其相似,我用matlab頻域抽取的話,是正確的,用C++實現就出了問題。

最佳回答:


找到了!這一行出了問題,K=m/(Nout/nSamples); C++默認=右側為整形數據 整形賦值給float類型,float沒有起到相應的作用,仍然為整形數據。所以抽取頻域數據的時候出現了問題~改為K=1.0*m/(Nout/nSamples); 即可

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved