Skip to content
AI360Xpert
Beta

Spectral Analysis

Spectral analysis estimates how signal power spreads over frequency from finite noisy samples, trading resolution against variance.

One raw periodogram wobbles wildly around the truth while averaging over windows steadies the estimate onto the two true peaks
One raw periodogram wobbles wildly around the truth while averaging over windows steadies the estimate onto the two true peaks

Why Does This Exist?

A measured trace mixes tones, broadband noise, and interference; decisions (bearing fault? grid oscillation? seizure onset?) need power per frequency with uncertainty attached. The raw periodogram (squared DFT magnitudes) is unbiased but inconsistent: its variance never shrinks with more data, so longer records merely add wobblier bins. Spectral analysis fixes estimation: windowed, averaged, and tapered variants that trade resolution for stability with stated degrees of freedom. Transforms are Fourier; time-localized alternatives are wavelets.

The one idea you need first

The power spectral density S(f)S(f) gives power per Hz: tone power concentrates in lines, white noise spreads flat at σ2/fs\sigma^2/f_s per bin. Estimates S^\hat{S} report power per bin with chi-square fluctuations around SS.

Think of It Like This

Weighing flour with a shaky scale

One scale reading flickers wildly: 9898, 105105, 9393 grams for the same scoop. Averaging ten scoops steadies the mean but blurs whether the flour came in one pour or two (resolution lost). A steadier scale (tapered, damped) reads calmer per scoop but responds slower to sudden changes.

Periodograms are the shaky scale: each bin reads S(f)S(f) times exponential noise (standard deviation equals the mean). Welch averaging trades frequency sharpness for calm; multitapers trade measurement count for leakage control. No estimator is both sharpest and calmest.

How It Actually Works

Periodogram: S^P(k)=∣Xk∣2/(fsn)\hat{S}_P(k) = |X_k|^2 / (f_s n), variance ≈S2\approx S^2 per bin regardless of nn (2 degrees of freedom). Bartlett/Welch: split into MM segments (Welch: overlapping, windowed), average: variance /M/M, resolution ×M\times M coarser, degrees of freedom 2M2M. Multitaper: KK orthogonal Slepian tapers on the full record: 2K2K degrees of freedom at full resolution minus bandwidth WW widening. Rule: M≥8M \ge 8 segments (or K≥5K \ge 5 tapers) before quoting levels.

Worked example

Bearing vibration at fs=12,800f_s = 12{,}800 Hz, n=12,800n = 12{,}800 samples (11 s): fault tone 320320 Hz at power 4.04.0 (mm/s)2\text{mm/s})^2, noise floor 0.040.04 per bin (ratio 100100: 2020 dB). Raw periodogram bins fluctuate with standard deviation equal to the mean: noise bins read 0.00.0 to 0.20.2 (some crossing 10%10\% of the tone); the tone bin reads 0.50.5 to 1212 across realizations. Welch with M=8M = 8 half-overlapping Hann segments: noise standard deviation falls to 0.04/8≈0.0140.04/\sqrt{8} \approx 0.014; tone resolves at 4.0±1.44.0 \pm 1.4 with 1616 degrees of freedom; 95%95\% interval [2.2,7.5][2.2, 7.5] (chi-square): detection margin 2.2/0.068≈322.2/0.068 \approx 32 above the noise ceiling. Decision-grade where raw was not.

Code

import cmathimport math

def periodogram(xs: list[float], fs: float) -> list[float]:    n = len(xs)  # squared magnitudes scaled to power per bin    out = []    for k in range(n // 2 + 1):        s = sum(x * cmath.exp(-2j * cmath.pi * k * t / n) for t, x in enumerate(xs))        out.append(round(abs(s) ** 2 / (fs * n), 4))    return out

tone = [2 * math.cos(2 * math.pi * 2 * t / 16) for t in range(16)]spec = periodogram(tone, 16.0)print(spec.index(max(spec)), round(max(spec), 2))  # -> bin 2, power 4.0

Tone power 4.04.0 lands in bin 22 exactly (frequency 22 Hz at 11 s): the estimator finds the line where planted.

Watch Out For

Quoting raw periodogram levels as measurements

Single-bin periodogram values carry 100%100\% relative standard deviation: a "66 dB rise" in one bin is one standard wobble, not an event. Average to stated degrees of freedom (M≥8M \ge 8) before alerting, trending, or thresholding anything.

Windowing away closely spaced tones

Heavy windows (Blackman) widen main lobes 33 times: tones 1010 Hz apart at 88-Hz resolution merge into one. Match taper to the question (detect presence: average hard; separate neighbors: window light, record long) instead of defaulting to Hann everywhere.

The Quick Version

  • Power spectra report power per frequency with chi-square fluctuations per bin.
  • Raw periodograms never steady with record length: variance equals the mean squared.
  • Welch with 88 segments cuts noise deviation to 0.0140.014 and gives 1616 degrees of freedom.
  • The fault tone at 4.04.0 stands 3232 times above the noise ceiling after averaging.
  • Multitapers keep resolution while buying stability through orthogonal windows.
  • Average before alerting; window lightly when tones sit close.