问题
I have the following MATLAB code to compute the PSD of a signal:
x = linspace(0, 10, 100001);
dt = x(2) - x(1);
Fs = 1 / dt;
a1 = 1;
f1 = 500;
a2 = 10;
f2 = 2000;
y = a1 * sin(2*pi*f1*x) + a2 * sin(2*pi*f2*x);
nblock=1024;
overlap=128;
windowsel=hann(nblock);
[Pxx,f]=pwelch(y,windowsel,overlap,nblock,Fs,'onesided');
figure()
semilogy(f,Pxx, '-o')
I have tried to reproduce the same calculation using welch
in scipy.signal
. However, for low frequency, the behavior is clearly not the same. I have checked that the hanning window is the same in both. What other parameter can I change in order to reproduce the results?
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import welch, hanning
x = np.linspace(0, 10, 100001)
dt = x[1] - x[0]
fs = 1 / dt
a1 = 1
f1 = 500
a2 = 10
f2 = 2000
y = a1 * np.sin(2*np.pi*f1*x) + a2 * np.sin(2*np.pi*f2*x)
datos = y
nblock = 1024
overlap = 128
win = hanning(nblock, True)
f, Pxxf = welch(datos, fs, window=win, noverlap=overlap, nfft=nblock, return_onesided=True)
plt.semilogy(f, Pxxf, '-o')
plt.grid()
plt.show()
MATLAB:
PYTHON:
回答1:
The problem is solved when using detrend=False
as stated in the GitHub issue https://github.com/scipy/scipy/issues/8045#issuecomment-337319294
回答2:
Your parameters seem correct and I can reproduce your result in Python.
An explanation for the difference is possibly the different implementation of the Welch' method in MATLAB and SciPy. Looking at the graph and that the behavior manifests only close to zero I find this likely.
You could try to play with input values (window length, sample frequency, FFT length) a little bit and see if the problem persists. If not you may have found an edge case (perhaps do to numerical errors) in the function and there is nothing you can do about it apart from digging into the implementation details which is not possible in MATLAB's case.
来源:https://stackoverflow.com/questions/46775223/equivalence-scipy-signal-welch-to-matlab-pwelch