0
$\begingroup$

What works:

  1. I generate real-valued white gaussian noise with standard deviation $\sigma$
  2. I calculate the FFT of this noise. The Abs of the FFT is a flat noisy trace over frequency, as expected for white noise.
  3. The standard deviation of the resulting FFT returns $\sigma$. -> Expected, good!

Where I am stuck:

  1. I use the same noise vector, but now multiply it with a unity-gain Hann window, i.e. the Hann window whose tip is at a value of 2 and whose integral is equal to the vector length.
  2. I calculate the FFT and compute the standard deviation as before. The absolute value of the FFT again is a flat noisy trace over frequency, but the average value is somewhat higher as also reflected in the standard deviation of the FFT:
  3. The result of the standard deviation of the FFT vector is approximately $\sigma$ with an additional factor of approximately ~1.24.
  4. I am puzzled because the same unity-gain Hann window does not alter the amplitude of Sine waves in the FFT.

Questions:

  1. Why does applying this Hann window change the noise power ?
  2. What is the exact value of the additional factor and why ? I am unable to derive it formally.
  3. Is it perhaps $\sqrt{3/2}\approx1.225$ ? I obtained it as square root of the integral of the squared window.. The same factor would be indeed 1 for the unity gain rectangular window.

Code example (Mathematica):

n = 2000;
noise = RandomVariate[NormalDistribution[0, 1.], n];
win = 1 - Cos[2 \[Pi] Range[n]/n];
StandardDeviation@Fourier[noise]        (* returns ~1.00 *)
StandardDeviation@Fourier[noise*win]    (* returns ~1.24 *)
$\endgroup$
2
  • $\begingroup$ hm, what's the sum of squares of the window, both in discrete time and discrete frequency (the latter two should be at least proportional, thank's to Parseval's theorem) $\endgroup$ Oct 20, 2022 at 11:57
  • $\begingroup$ @MarcusMüller I think I don't understand your comment. The sum of the window values is $n$ (vector length). The sum of squares of the Hann window is $\frac{3}{2}n$. Does this "answer" your comment ? $\endgroup$
    – tobalt
    Oct 20, 2022 at 12:14

2 Answers 2

2
$\begingroup$

I obtained it as square root of the integral of the squared window.

That's the correct scaling. Assuming we use a DFT scaling of $1/\sqrt{N}$ for both the forward and backward transforms, Perceval's theorem holds, i.e.

$$\sum x^2[n] = \sum |X[k]|^2$$

This means the energy in frequency and time is always the same and there is no need to consider this in the frequency domain at all, we can do all of this in the time domain.

You want the power and after windowing to match. That is

$$ <x^2[n]> = <(G\cdot x[n]\cdot w[n])^2> $$

Where $G$ is the amplitude scaling factor required to match the energies with and without window. Since the window and white noise are uncorrelated we have $<(x[n]\cdot w[n])^2> \approx <x^2> \cdot <w^2>$ and the calibration factor becomes

$$G = \sqrt{ \frac{<x^2>}{<x^2> \cdot <w^2>}} = \frac{1}{\sqrt{<w^2>}}$$

which is the inverse of the RMS of the window. For a Hanning window that comes out to be

$$ G = \sqrt{8/3} $$

$\endgroup$
4
  • $\begingroup$ Since the window and white noise are uncorrelated - does that mean that the calibration factor here is different than for amplitude estimation of sine waves, because the sine waves are correlated with the window ? And second, how does this $\sqrt 8$ relate to the factor of $\sqrt{3/2}$ that you say is correct? $\endgroup$
    – tobalt
    Oct 20, 2022 at 13:26
  • 1
    $\begingroup$ Sorry, I had my math wrong. It's corrected now. We have to use RMS instead variance since, the window is not mean-free. Your original scale factor was $2$ and the correct one is $\sqrt{8/3}$ , The ratio between the two is indeed $\sqrt{3/2}$ $\endgroup$
    – Hilmar
    Oct 20, 2022 at 13:30
  • $\begingroup$ Correlation is complicated. The window will correlate with some sine waves but not with others. Same for most other signals. $\endgroup$
    – Hilmar
    Oct 20, 2022 at 13:40
  • $\begingroup$ This is not the first time I see this kind of question (on why the power gain is computed that way) and have never seen a satisfying answer. I think the part about the window and white noise being uncorrelated and the consequence should be elaborated $\endgroup$
    – mocquin
    Jul 12 at 15:03
1
$\begingroup$

Well, think about the middle of the Hann window: it is multiplying the noise at that sample by 2. Assuming $\epsilon[t]$ (the noise sequence) is zero-mean, then: $$ E[\epsilon[t_{\tt mid}]^2] = \sigma_\epsilon^2\\ E[(2\epsilon[t_{\tt mid}])^2] = 4\sigma_\epsilon^2 $$

You are correct about the factor: $$ E[(w_{\tt Hann}[t]\epsilon[t])^2] = w_{\tt Hann}^2[t]E[\epsilon[t]^2] = w_{\tt Hann}^2[t]\sigma^2_{\epsilon} $$ so when the windowed noise sequence is square-summed, the value will be (on average) the sum of the squares of the window.

The code below gives the output:

0.9993634555439993
1.2233491702059618
1.224744871391589

So you can see that the average value is very close to the $\sqrt{3/2}$.

As for the sine components, think about what the window looks like in the frequency domain:

$$ w[t] = \frac{1}{2} \left[ 1 - \cos(2\pi \frac{t}{n})\right] \leftrightarrow W[k] = \left \{ \begin{align} 1, \ \ &k = 0\\ -0.5, \ \ &|k| = 1\\ 0, \ \ &\mbox{otherwise} \end{align} \right . $$ So that at the center frequency, the gain is 1 (normalized to the window length).

The difference between the random signal and the sinusoid is that the sinusoidal energy is now distributed across the three bins: $k$, $k+1$ and $k-1$. You can see this if you do:

sine_wave = np.sin(2*np.pi*100/n*np.arange(n))

plt.plot(np.abs(np.fft.fft(sine_wave)))
plt.plot(np.abs(np.fft.fft(win*sine_wave)))
plt.xlim([90,110])

which shows:

Showing spread of energy across three bins instead of one.

Have a read through fred harris's paper On the Use of Windows for Harmonic Analysis with the Discrete Fourier Transform. He calls this effect the processing gain or the coherent gain.


Code Only Below

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(85022)

n_iterations = 1000
std_sum = 0
std_win_sum = 0

n = 2000
win = 1 - np.cos(2*np.pi*np.arange(n)/n);

for iter in np.arange(n_iterations):
    noise = np.random.randn(n)

    std_sum = std_sum + np.std(noise)
    std_win_sum = std_win_sum + np.std(noise*win)
    
print(std_sum/n_iterations)
print(std_win_sum/n_iterations)
print(np.sqrt(np.sum(np.power(win,2))/n))
$\endgroup$
4
  • $\begingroup$ Does it have to do with the uncorrelated vs. time-correlated nature of noise signals vs. sine wave signals, that the noise is scaled up by the unity-gain window, but the sine amplitudes are not ? That bit is a bit hard for me to wrap my head around. $\endgroup$
    – tobalt
    Oct 20, 2022 at 13:29
  • $\begingroup$ @tobalt Added more explanation for the sinusoidal component piece. $\endgroup$
    – Peter K.
    Oct 20, 2022 at 13:59
  • $\begingroup$ Thanks.. But for noise at frequency k (which is also a sine wave) it still gets the gain from the window, while the isolated sine wave doesn't. This is what is confusing me. $\endgroup$
    – tobalt
    Oct 20, 2022 at 15:49
  • $\begingroup$ @tobalt The difference is that the sinusoid, being highly correlated with the $k$th Fourier coefficient will spread its energy over three bins, not just the one. See my update. $\endgroup$
    – Peter K.
    Oct 20, 2022 at 16:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.