Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Open
Labels
Description
Bug summary
If my understanding is correct:
NFFT
ofmlab._spectral_helper
corresponds tonperseg
of spectral funtions ofscipy.signal
.
It's the actual length of signal (segment) for DFT.pad_to
ofmlab._spectral_helper
corresponds tonfft
of spectral funtions ofscipy.signal
.
It's the length of DFT, i.e. parametern
offft
funtion.matplotlib/lib/matplotlib/mlab.py
Line 385 in3418bad
result=np.fft.fft(result,n=pad_to,axis=0)[:numFreqs, :]
But the implementation of Matplotlib is really confusion:
If length of signal is less than NFFT, signal will pad to length of NFFT.
matplotlib/lib/matplotlib/mlab.py
Lines 342 to 351 in3418bad
# zero pad x and y up to NFFT if they are shorter than NFFT iflen(x)<NFFT: n=len(x) x=np.resize(x,NFFT) x[n:]=0 ifnotsame_dataandlen(y)<NFFT: n=len(y) y=np.resize(y,NFFT) y[n:]=0 And the window is determined by NFFT instead of actual length of signal. This would cause wrong window correction.
matplotlib/lib/matplotlib/mlab.py
Lines 376 to 380 in3418bad
ifnotnp.iterable(window): window=window(np.ones(NFFT,x.dtype)) iflen(window)!=NFFT: raiseValueError( "The window length must match the data's first dimension") The Nyquist frequency is
NFFT/2
instead ofpad_to/2
.matplotlib/lib/matplotlib/mlab.py
Lines 411 to 416 in3418bad
# if we have a even number of frequencies, don't scale NFFT/2 ifnotNFFT%2: slc=slice(1,-1,None) # if we have an odd number, just don't scale DC else: slc=slice(1,None,None)
Code for reproduction
importnumpyasnpfrommatplotlibimportmlabfs=1000t=np.arange(0,1,1/fs)rng=np.random.default_rng(42)s=np.sin(2*np.pi*100*t)+0.5*rng.normal(size=t.shape)nfft=2048nsignal=len(s)#1000psd,freqs=mlab.psd(s,NFFT=nfft,Fs=fs,window=mlab.window_none)mag=np.abs(np.fft.rfft(s,n=nfft))psd1= (mag)**2/nsignal/fsifnotnfft%2:psd1[1:-1]*=2else:psd1[1:]*=2relative_error=np.abs(2* (psd-psd1)/(psd+psd1) )print(relative_error.max())
Actual outcome
0.6876640419947717
Expected outcome
0