14

C++/C を使用して、レーザーのパルス出力であるはずのデータに対して順方向および逆方向の FFT を実行しています。

アイデアは、出力を取得し、フォワード FFT を使用して周波数ドメインに変換し、位相に線形最適適合を適用し (最初にアンラップ)、次にこの最適適合を位相情報から差し引くことです。

得られた位相と振幅は時間領域に変換され、最終的な目的は位相補償によるパルスの圧縮です。

私はこれを MATLAB で実行しようとしましたが失敗し、結果として C++ に変更しました。フォワード FFT は正常に動作しています。C++ の数値レシピから基本的なレシピを取得し、次のように関数を使用して複雑な入力用に変更しました。

void fft(Complex* DataIn, Complex* DataOut, int fftSize, int InverseTransform, int fftShift)
{

        double* Data  = new double[2*fftSize+3];
        Data[0] == 0.0;


        for(int i=0; i<fftSize; i++)
        {
                Data[i*2+1]  = real(DataIn[i]);
                Data[i*2+2]  = imag(DataIn[i]);
        }

        fft_basic(Data, fftSize, InverseTransform);

        for(int i=0; i<fftSize; i++)
        {
                DataOut[i] = Complex(Data[2*i+1], Data[2*i+2]);
        }

        //Swap the fft halfes
        if(fftShift==1)
        {
                Complex* temp = new Complex[fftSize];
                for(int i=0; i<fftSize/2; i++)
                {
                        temp[i+fftSize/2] = DataOut[i];
                }
                for(int i=fftSize/2; i<fftSize; i++)
                {
                        temp[i-fftSize/2] = DataOut[i];
                }
                for(int i=0; i<fftSize; i++)
                {
                        DataOut[i] = temp[i];
                }
                delete[] temp;
        }
        delete[] Data;
}

ftt_basic()「数値レシピ C++」から取得した関数を使用します。

私の問題は、入力の形式が逆 FFT の出力に影響を与えるように見えることです。これは精度の問題かもしれませんが、私は周りを見回しましたが、これまでに他の人に影響を与えたようには見えません.

フォワード FFT の出力をリバース FFT に直接戻すと、入力と同じパルスが生成されます。

ここに画像の説明を入力

ただし、フォワード FFT の時点で得られた電力出力を取得しreal^2+imag^2、次のような配列にコピーします。

Reverse_fft_input[i]=complex(real(forwardsoutput[i]),imag(forwardsoutput[i]));

これを逆 FFT の入力として使用すると、次の結果が得られます。 ここに画像の説明を入力

そして最後に、フォワード FFT の出力を取得し、次のようにコピーします。

Reverse_fft_input[i]=complex( Amplitude[i]*cos(phase[i]), Amplitude[i]*sin(phase[i]));

ここで、Amplitude[i]=(real^2+imag^2)^0.5 および phase[i]=atan(imag/real) です。時間領域に戻すと、次の電力出力が得られます。

ここに画像の説明を入力

パルス構造を詳しく見てみましょう。

ここに画像の説明を入力

最初の写真がきれいで規則的なパルスを生成したとき。

私の質問は、逆fftの出力がこのようになる原因となるcos関数とsin関数の精度ですか?複素数データを入力するさまざまな方法に大きな違いがあるのはなぜですか? また、データが逆 FFT に直接フィードバックされた場合にのみ、時間領域のデータが元のデータと同一になるのはなぜですか? forwads FFT への入力?

ありがとうございました。

*ここでの編集は、機能の実装です:

void TTWLM::SpectralAnalysis()

{

    Complex FieldSpectrum[MAX_FFT];
    double  PowerFFT[MAX_FFT];
    double  dlambda;
    double  phaseinfo[MAX_FFT]; // Added 07/08/2012 for Inverse FFT
    double  fftamplitude[MAX_FFT]; // Added 07/08/2012 for Inverse FFT after correction
    double  phasecorrect[MAX_FFT]; // Added 07/08/2012 for Inverse FFT after correction
    double  lambdaarray[MAX_FFT]; // Added 07/08/2012 for Inverse FFT after correction
    Complex CompressedFFT[MAX_FFT];
    Complex correctedoutput[MAX_FFT];


    //Calc the wavelength step size
    dlambda = lambda*lambda/CONST_C/DT/fftSize;
    //Calculate the spectrum
    fft(fftFieldData, FieldSpectrum, fftSize, FORWARD, SHIFT); // Forward fft of the output data 'fftFieldData' into frequency domain

    //Get power spectrum
    for(int i=0; i<fftSize; i++)
    {

        PowerFFT[i]                  = norm(FieldSpectrum[i]);
        phaseinfo[i]                 = atan2(imag(FieldSpectrum[i]),real(FieldSpectrum[i]));
        fftamplitude[i] = sqrt(PowerFFT[i]);      // Added 07/08/2012 for Inverse FFT after correction


    }

    // Added 07/08/2012 for Inverse FFT after correction, this loop subtracts line of best fit from the phase

        for(int i=0; i<fftSize; i++)
    {
        lambdaarray[i]=dlambda*(i-fftSize/2)*1e-2;
        phasecorrect[i]=phaseinfo[i]-((1.902e+10*lambdaarray[i])+29619); // Correction from best fit in MATLAB (DONE MANUALLY) with phase unwrapping
        CompressedFFT[i]=(fftamplitude[i]*cos(phaseinfo[i]),fftamplitude[i]*sin(phaseinfo[i]));
            }

       fft(CompressedFFT, correctedoutput, fftSize, REVERSE, SHIFT); // Reverse fft of corrected phase back to time domain, final output is correctedoutput

再度、感謝します!

4

1 に答える 1

2

いくつかの可能性のあるエラー:

   Data[0] == 0.0;

おそらくそうでは=ない==でしょうか?

fft_basic(データ、fftSize、InverseTransform);

この関数のソースにはアクセスできません。奇数の場所に実部、偶数の場所に虚数で提供しているレイアウトを本当に期待していますか?

    //Swap the fft halfes

他の質問で言ったように、それらを交換する場合は、逆変換の前に元に戻す必要があります。このスワップを実行しますか?

あなたのデータは fft_basic 関数の期待と一致していますか? おそらく、fftSize が 2 のべき乗であることを期待しています。

FFT結果を正規化しますか? 離散 FFT 変換には正規化が必要です。

于 2012-08-21T20:36:30.093 に答える