Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency in function PSD when the NFFT parameter is an odd number #4324

Closed
cvr opened this issue Apr 10, 2015 · 1 comment
Closed

Inconsistency in function PSD when the NFFT parameter is an odd number #4324

cvr opened this issue Apr 10, 2015 · 1 comment
Assignees
Milestone

Comments

@cvr
Copy link

cvr commented Apr 10, 2015

Function mlab.psd appears to have one inconsistency if the NFFT parameter is an odd number. In such case, as the highest frequency is not the Nyquist frequency, instead is int(.5*NFFT)/float(dt*NFFT), there are two distinct values showing both at the positive and negative frequencies in the FFT result. Consider the following example:

import numpy as np
from matplotlib import mlab
u = np.array([0, 1, 2, 3, 1, 2, 1])
dt = 1.0
Su = np.abs(np.fft.fft(u) * dt)**2 / float(dt * u.size)
P, f = mlab.psd(u, NFFT=u.size, Fs=1/dt, window=mlab.window_none,\
    detrend=mlab.detrend_none, noverlap=0, pad_to=None, scale_by_freq=None,\
    sides='onesided')

The resulting arrays Su and P are:

Su = [ 14.29, 1.61, 0.69, 0.55, 0.55, 0.69, 1.61 ]
P  = [ 14.29, 3.23, 1.39, 0.55 ]

To convert Su to one-sided output, it is common to sum the Fourier coefficients corresponding to negative and positive frequencies. Considering that u.size is odd, the frequencies which correspond to the coefficients in Su are:

df = 1 / float(u.size * dt)
f = np.array([ 0, 1, 2, 3, -3, -2, -1 ]) * df

thus, as the Su[1:4] are the positive side coefficients and Su[4:] the negative side, all coefficients are summed except for Su[0] (which in this case, as u is real is the same as Su[1:4] * 2):

Su_1side = np.append([Su[0]], Su[1:4] + Su[4:][::-1])

This results in Su_1side = [ 14.29, 3.23, 1.39, 1.10 ], whose last coefficient differs from the result of P, i.e. the mlab.psd result.

Note that the lack of scaling of the last coefficient is not a problem when the NFFT is an even number. In such case, as the as the frequency array is:

f = [ 0, df, 2*df, ..., (fnyquist - df), -fnyquist, -(fnyquist - df), ..., -2*df, -df ]

there is only one coefficient for the highest frequency (fnyquist), thus it is not summed up with another coefficient.

@tacaswell tacaswell modified the milestones: next point release, proposed next point release Apr 10, 2015
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Apr 10, 2015
@tacaswell tacaswell self-assigned this Apr 10, 2015
@tacaswell
Copy link
Member

Thank you for the detailed bug report and explanation of what we were doing wrong!

Should be fixed by #4326

In [6]: P
Out[6]: array([ 14.28571429,   3.22739913,   1.38941047,   1.09747611])

@tacaswell tacaswell modified the milestones: Color overhaul, proposed next point release Apr 10, 2015
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Apr 12, 2015
e-q added a commit to e-q/scipy that referenced this issue Apr 12, 2015
See matplotlib/matplotlib#4324 for description of the problem. The
previous welch algorithm suffered from the same bug, so the unit tests
had to be updated/corrected as well.
e-q added a commit to e-q/scipy that referenced this issue May 5, 2015
See matplotlib/matplotlib#4324 for description of the problem. The
previous welch algorithm suffered from the same bug, so the unit tests
had to be updated/corrected as well.
fariza pushed a commit to fariza/matplotlib that referenced this issue May 15, 2015
@tacaswell tacaswell modified the milestones: Color overhaul, next major release (2.0) Oct 26, 2015
@QuLogic QuLogic modified the milestones: v1.5.0, 2.0 (style change major release) Oct 16, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants