Power Spectral Density with NMath
Application Note
Power Spectral Density Calculation
I’ve had several customers ask about computing the PSD in C# with NMath, so I though it was time for a post on the subject. The power spectral density provides an estimate of the power present within each slice of spectrum, and is presented as graph of the signal power versus frequency. It’s a common signal processing calculation across many fields from acoustics to chemistry, and can provide insight into periodicities contained within a time domain signal.
For stationary, square summable signals, the PSD is expressed as,
where F(w) is the Fourier transform of the time domain signal f(t), and T is the width of the time domain sampled signal. Naturally we can never sample the entire signal, so calculations of the PSD are all estimates. Techniques for estimating the PSD can be divided into two classes, parametric (model based), and nonparametic (non-model based). We will discuss only nonparametic techniques here. For discrete signals that are not square summable (i.e. non-stationary signals – and so the Fourier transform does not exist), estimates of the power spectral density can be derived from,
Which is the Fourier transform of the autocorrelation as the correlation width of the sampled signal tends to infinity. For a concise derivation of both of these formulas read these short lecture notes.
Computing the PSD using NMath
Concentrating on stationary (periodic) signals, the PSD is most efficiently computed by applying smoothing to discrete
Where n is the number of signal samples. Each point in the periodogram represents the relative contribution to the variance in the time domain signal at that frequency. (Visualization provided courtesy of Infragistics.)

An example periodogram of sunspot data. This is smoothed in some fashion to estimate the PSD.
Another estimation technique involves computing multiple windowed periodograms and then combining these together to get a progressively more accurate estimate (Welch’s Method, similarly MTM with Slepian windows). The time domain signal should be detrended before any of these operations.
The following C# code estimates the PSD by smoothing the periodogram using a Savitzy-Golay zero phase shift filter.
using CenterSpace.NMath.Core; public DoubleVector PSDEstimate(DoubleVector data) { // Detrend the periodic data data = data - NMathFunctions.Mean(data); // Compute the periodogram DoubleForward1DFFT forwardFFT = new DoubleForward1DFFT(data.Length); DoubleVector pspacked = forwardFFT.FFT(data); DoubleSymmetricSignalReader reader = forwardFFT.GetSignalReader(pspacked); DoubleComplexVector fft = reader.UnpackSymmetricHalfToVector(); DoubleVector pg = NMathFunctions.Abs(fft)/fft.Length; // Smooth w/ filter of width of 7, & polynomial degree of 5. SavitzkyGolayFilter sgf = new SavitzkyGolayFilter(3, 3, 5, 0); DoubleVector smoothedPSD = sgf.Filter(pg); return smoothedPSD; }
Or using a Daniell filter and the MovingWindowFilter class to smooth the periodogram.
MovingWindowFilter mwf = new MovingWindowFilter(2, 2, new DoubleVector(.125, .25, .25, .25, .125)); mwf.WindowBoundaryOption = MovingWindowFilter.BoundaryOption.PadWithZeros; DoubleVector smoothedPSDaniell = mwf.Filter(data);
More information about NMath’s FFT class set can be found on our fft landing page. The class SavitzkyGolayFilter will be avaliable in our next release, however, current users can use the MovingWindowFilter class with Savitzky-Golay coefficients generated via a provided helper method.
Happy Computing,
Paul
References
Haykin, S. “Adaptive Filter Theory”. Prentice-Hall, Inc. 1996.
Tags: C# power spectral density, estimating PSD, fft C#, filtering c#, power spectral density, PSD .NET, PSD C#
