Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Bug]: Possible problem with parameterNFFT andpad_to ofmlab._spectral_helper #24822

Open
@gapplef

Description

@gapplef

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.
    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.

    # 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.

    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 isNFFT/2 instead ofpad_to/2.

    # 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp