[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: bug in IDL's hanning() window-generating function
There is no doubt that the IDL supplied hanning window is symmetric but not
"fft-symmetric" as it should be for fft processing. I would guess that for
most applications this difference will not significantly impact the results,
but for situations where there is a large signal to noise ratio ( > 80 dB)
with a sinusoidal signal exactly centered in an fft bin there can be major
differences between the two windows. Most real world problems (at least that
I have come across) dont meet this situation and the observed differences
are minor. Of course there is no reason to use the wrong window when the
correct one is easily generated.
> In article <3B681285.B12C4939@fz-juelich.de>,
> Jaco van Gorkom <firstname.lastname@example.org> wrote:
> >David Fanning wrote:
> >> Scott Bennett writes after a long analysis of the Hanning function:
> >> > In any case, I think the point Harris made is that a discrete
> >> > sampling of a window function should not taper to the same value at
> >> > the end that it has at the beginning because to do so would include
> >> > the first sample of the *next* period (windowed segment.) So IDL's
> >> > hanning() gets it wrong for both even- and odd-length windows. :-(
> >> Uh, huh. And how did RSI respond when you contacted them
> >> about it?
> >I suspect they would suggest the following workaround:
> >function Harris, n, _EXTRA=extra
> > return, (hanning(n+1, _EXTRA=extra))[0:n-1]
> That looks like it should work for Hann, Hamming, and other
> raised cosine windows. I am not prepared to vouch for that method
> for all windows.
> >Scott, I've read your post, but I'm not sure I'm getting the point.
> >Tapering from zero to zero seems like good idea to me, the symmetry
> >sort of "feels good". Besides, it is convenient to have the weight of
> >the window at its centre. What exactly is so wrong with it?
> First, remember that a continuous, finite Fourier transform
> operates over a time (or space, but I'm just going to refer to time)
> domain of finite length T. The lowest frequency that can be resolved
> is the one whose period 1/f = T; i.e. one full period takes exactly
> the length of the time over which the integral operates.
> So now consider a periodic function at that frequency. Take,
> for example, a sine function like y = cos(2 pi t/T), where 0 le t lt T.
> Note that the function begins at cos(0)=1. The assumption underlying
> the Fourier transform is that the basis functions are all periodic.
> So the finite Fourier transform is based upon the same assumption, but
> also that the function value over the time period from 0 to T exactly
> repeats ad infinitum. Therefore the time period is closed at the
> starting point and open at the ending. The open end is the point at
> which the cycle is assumed to begin its repetition of the starting
> point; i.e. it's the starting point of the next cycle or period, if
> another cycle were to exist.
> The discrete, finite Fourier transform operates upon a sampling
> of the continuous function taken at N regular intervals of length
> delta t, so the samples are at n * delta t, where n = 0, 1, 2, ..., N-1.
> Note that a sample taken at t = N * delta t represents the point at
> which the cycle would repeat if more samples existed because the
> samples are taken at the start of each time interval, not at the end
> of each time interval. (A data window is supposed to have the same
> period as the data being windowed, so the data window's period likewise
> is closed at the left (starting) end and open-ended at the right.)
> To see what happens when the discrete transform is applied to one
> too many samples, try the following. (Set color1 and color2 to vividly
> contrasting colors in your preferred color table.)
> samples = cos(2. * !pi * findgen(9)/ 8.)
> That gives us a sampled cosine function for one period of eight
> samples, plus an extra for our experiment. Next, get the discrete
> transforms and look at them.
> gooddft = fft(samples[0:7])
> baddft = fft(samples)
> plot, float(gooddft), /nodata, yrange=[-.4, .6]
> oplot, float(gooddft), psym=1, color=color1
> oplot, imaginary(gooddft), psym=7, color=color2
> The above should yield a graph with a color1 (real component) spike of
> .5 above the points for 1 and 7, corresponding to frequencies of 1/T
> and -1/T, and zeros everywhere else (within the limits of precision,
> etc.,) and color2 (imaginary component) values of zero everywhere.
> Then try:
> plot, float(baddft), /nodata, yrange=[-.4, .6]
> oplot, float(baddft), psym=1, color=color1
> oplot, imaginary(baddft), psym=7, color=color2
> This should give a graph showing a non-zero real (color1) mean value
> over the zero frequency, real (color1) peaks over the points 1 and 8,
> corresponding to frequencies of 1/T and -1/T, but a little higher than
> a value of .5 and imaginary (color2) points just less than .2 and just
> greater than -.2 over the same horizontal positions. Note that real
> and imaginary components of other frequencies are also non-zero. We
> know this cannot be correct because we specified the generating
> function to have only one frequency, which the transform splits in
> half over the symmetric frequencies of 1/T and -1/T, and we know that
> the mean of a cosine function over one complete period is zero. The
> amplitudes (both real and imaginary) of all other frequencies should
> be zero.
> So a Hann window, and other windows I've seen so far, should not
> include a repetition of its first coefficient as the last coefficient.
> Scott Bennett, Comm. ASMELG, CFIAG
> College of Oceanic and Atmospheric
> Oregon State University
> Corvallis, Oregon 97331
> * Internet: sbennett at oce.orst.edu *
> * "Lay then the axe to the root, and teach governments humanity. *
> * It is their sanguinary punishments which corrupt mankind." *
> * -- _The_Rights_of_Man_ by Tom Paine (1791.) *