2017-03-15 16 views
1

私はFFTの結果である(CsCoreから)を持っています。パワースペクトル密度fft結果からC#

Complexは、float realおよびfloat imaginaryを有する。次

  • 頻度を計算し、このIから

    (double)index * sampleRate/FftSize;

  • 振幅/大きさ:Math.Sqrt(Math.Pow(real, 2) + Math.Pow(imaginary, 2));
  • フェーズ:これらが間違っている場合Math.Atan(imaginary/real);

私を修正してください。

私が理解するところでは、これは周波数領域の情報であり、私のサンプルでどの周波数が最も一般的であるかを知ることができます。今私は時間の経過とともにパワー密度を見たいと思っています。 Matlab documentationは例を示していますが、私はMatlabを知らないので理解できません。誰かがこのテーマに関するMatlabのドキュメントを説明したり、C#の実装を手伝ったりできますか?

EDIT:
This answerは、単に振幅を二乗することをお勧めします。あれは正しいですか?

+0

[CsCore 'Complex'コード](https://github.com/filoe/cscore/blob/master/CSCore/Utils/Complex.cs)によれば、' float real'と 'float imaginary' 、ダブルではありません... – JHBonarius

答えて

2

確かに、私がthis other answerで述べたように、FFT結果の振幅を二乗することでパワースペクトル密度(PSD)の推定値を得ることができました。私のよう

psdx = (1/(Fs*N)) * abs(xdft).^2; 

:これはMatlab documentationから次の行は、あなたが(アップ異なる周波数成分の相対的な強さを比較することだけが必要なほとんどのアプリケーションにとって重要ではないスケーリングファクタに)状態を引用したものを、本質的ですまた、私の他の答えに記載されMatlabのドキュメントにも記載されている、FFTを取る前にwindow functionであなたの信号を乗算し、複数のFFT結果の二乗の大きさを平均することによって、より良いPSD推定値を得ることができます。

注:あなたがより良いMath.Atan2(imaginary, real)添えられる相用Math.Atan2 on MSDNを参照してください)(のみ[-pi/2,pi/2]をカバー代わりにMath.Atan()[-pi,pi]範囲を入力しますカバーしています。

+0

私は本当にどのようにウィンドウを使用するか分からない。私はhann(0.50f *(1 - (float)Math.Cos((2 * Math.PPI * n)/ N - 1)) ')の式を理解していますが、fftの前にウィンドウを使用しなければなりません私の波? –

+1

[Complex.Phase'プロパティ](https://msdn.microsoft.com/en-us/library/system.numerics.complex.phase(v = vs.110).aspx)を使用するだけであれば複素数a + biに対しては、Math.Atan2(b、a)を使用します。 – JHBonarius

+0

@GertKommerはい、波からN個のサンプルのチャンクがある場合は、ウィンドウ関数で要素を賢く掛けて、結果のFFTを取ります。 – SleuthEye

1

最初にMath.Sqrt(Math.Pow(real, 2) + Math.Pow(imaginary, 2));Complex.Magnitude propertyとして実装されています。またはComplex.Abs methodを使用することもできます。

SleuthEyeが言ったことに加えて、私は機能の実装についていくつか測定しました。私はMath.Pow(x,2)機能を信頼していなかったので

は私が実装さ:

private static double Square(double value) 
{ 
    return value * value; 
} 

しかし、それは、C#はすでにMath.Pow(x,2)を最適化していることが判明したので、それは十分に速いです。しかし、とにかく:

  1. 45 MS:次私は3つの実装

    1. Square(testData[idx].Real) + Square(testData[idx].Imaginary);
    2. Square(testData[idx].Magnitude);
    3. Square(Complex.Abs(testData[idx]));

    マイ(平均)結果(10,000,000複合要素のため)であったのと比較し

  2. 220ミリ秒
  3. 211ミリ秒

だから、マグニチュードプロパティおよびABSの方法は、プロセスにサイクルを要しており、内部で平方根を使用しているようです。しかし、PSDの場合は、その必要はありません。

+0

標準のComplexクラスではなく、CsCoreのComplexクラスを使用しています。悲しいことに、大きさと位相はありません。あなたの答えの残りの部分については、私は本当にそれをどうすればいいのか分かりません。 –

+0

あるタイプを別のタイプに変換してより多くの機能を使用できるようにする価値があることもあります)しかし、私は何を言おうとしていますか:最初に絶対/大きさを決定します(CsCoreでは「Complex.Value」と呼ばれます)結果を二乗することは非常に非効率的である。 – JHBonarius

+0

私は恥ずかしく、私は 'Complex.Value'を見ませんでした。 PSDの場合、大きさを二乗する必要があります。次に、「Complex.Value」または自分の書込み関数がSys数値よりも速いのですか? –

関連する問題