I have a Complex[]
(from CsCore) which is the result of my FFT.
Complex
has a float real
and a float imaginary
.
From this I calculated the following
(double)index * sampleRate / FftSize;
Math.Sqrt(Math.Pow(real, 2) + Math.Pow(imaginary, 2));
Math.Atan(imaginary / real);
If these are wrong please correct me.
From what I understand, this is the frequency domain information and it allows me to see which frequencies are most common in my sample. Now I want to see the power density over time. Matlab documentation shows examples, But I don't understand it because I don't know Matlab. Could someone explain the Matlab documentation on this subject or help me with a C# implementation?
EDIT:
This answer suggest to simply square the amplitude. Is that correct?
Indeed, as I stated in this other answer you could obtain a power spectrum density (PSD) estimate by squaring the amplitudes of the FFT results. This is essentially what the following line from the Matlab documentation you quoted states (up to a scaling factor, which is not significant for most applications requiring only to compare the relative strength of the different frequency components):
psdx = (1/(Fs*N)) * abs(xdft).^2;
As I also mentioned in my other answer, and is also described in Matlab documentation, you could get a better PSD estimate by multiplying your signal by a window function before taking the FFT, and averaging the squared-magnitude of multiple FFT results.
Note: for the phase you would be better served with Math.Atan2(imaginary, real)
(see Math.Atan2
on MSDN ) which covers the enter [-pi,pi]
range (instead of Math.Atan()
which only covers [-pi/2,pi/2]
).
Firstly Math.Sqrt(Math.Pow(real, 2) + Math.Pow(imaginary, 2));
is already implemented as the Complex.Magnitude
property . Or you can use the Complex.Abs
method .
In addition to what SleuthEye said, I did some measurements on function implementation.
Because I did not trust the Math.Pow(x,2)
function I implemented:
private static double Square(double value)
{
return value * value;
}
However, it turns out that C# already optimized Math.Pow(x,2)
, so it's fast enough. But anyhow: next I compared three implementations
Square(testData[idx].Real) + Square(testData[idx].Imaginary);
Square(testData[idx].Magnitude);
Square(Complex.Abs(testData[idx]));
My (average) results were (for 10,000,000 complex elements):
So it seems the Magnitude property and Abs method use a square root internally, which takes a lot of cycles to process. But for the PSD you don't need that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.