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

15 views (last 30 days)
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

Answers (1)

Hari
Hari on 11 Jun 2025
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!

Categories

Find more on Fourier Analysis and Filtering in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!