Accurately calculate the spectrum energy (scaling, window and other concerns)

8 次查看(过去 30 天)
Hi,
I am studying on how to calculate the energy within a frequency band. I tried to use the psd function as well as the fft function. The code is as follows.
h = spectrum.periodogram('Hann');
Hpsd = psd(h,xframe,'NFFT',2^13,'Spectrumtype','Twosided','Fs',Fs);
and
frame_fft = abs(fft(xframe.*hann(length(xframe)),2^13));
frame_psd = frame_fft.^2/Fs/length(xframe);
I found that the Hann window used in each function has a different gain, which leads to the different results.
So my question is how to get a PSD with accurate values (w/wo window function)? In addition, could anybody please explain why we need to divide the Fs and frame length to normalize the scale? I tried to look into the psd function but couldn't understand the 'KMU' variable which is the 'Normalizing scale factor'.
Any help will be appreciated, Bach

回答(1 个)

Hari
Hari 2025-6-11
Hi,
I understand that you're trying to compute the Power Spectral Density (PSD) accurately within a frequency band and have noticed discrepancies between results from the psd function and your custom FFT-based method—mainly due to the treatment of the Hann window and normalization factors.
I assume your goal is to obtain consistent and physically meaningful PSD values, ideally in units of power per Hz, regardless of the method used.
In order to compute the PSD with accurate values and understand the normalization, you can follow the below steps:
Step 1: Understand windowing and its effect
When you apply a window (like Hann) before FFT or PSD estimation, it reduces spectral leakage but also affects the overall power of the signal. So:
  • The window scales down the energy.
  • A correction (normalization) factor is needed to account for this loss.
In MATLAB, the "KMU" (Kaiser-Multiplication Unit) or more generally, the window correction factor, compensates for the energy drop due to windowing.
Step 2: Use the periodogram method with normalization
To obtain the PSD with correct scaling using FFT, use this approach:
  • Compute FFT with a Hann window.
  • Divide by the product of sampling frequency and an energy normalization constant.
The normalization factor is typically:
U = sum(win.^2)/length(win); % where win is the Hann window
Then PSD is:
PSD = (abs(FFT_output).^2)/(Fs * length(xframe) * U);
This makes the PSD units watts/Hz, assuming your signal is in volts.
Step 3: Why divide by Fs and length?
  • Dividing by Fs normalizes the power to a per-Hz basis.
  • Dividing by length(xframe) ensures the PSD is not dependent on the frame length.
  • The combination gives a density spectrum that integrates to the signal's total power.
Step 4: Use built-in methods carefully
If using the spectrum.periodogram method, note that it internally handles window gain correction via KMU, so you do not need to adjust it manually. But when writing your own with fft, you must apply these steps.
Refer to the documentation of "periodogram" for correct usage:
Also refer to:
Hope this helps!

类别

Help CenterFile Exchange 中查找有关 Fourier Analysis and Filtering 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by