scipy.signal.correlate与Matlab xcorr功能是否一致?
关于scipy.signal.correlate与Matlab xcorr功能一致性及结果差异的问题
我想确认scipy.signal.correlate是否和Matlab的xcorr功能一致,以下是我分别实现的代码,但两者生成的图像完全不同,恳请帮助排查问题。
Matlab 实现代码
Fs_=40175; t_max=10; t0_=0:(1/Fs_):t_max; s0_=chirp(t0_, 400, t_max, 10000) B_ = xcorr(y,s0_) %y是从加载文件中读取的列向量 t_B = 0:(1/Fs_):(1/Fs_)*(length(B_)-1) t_B = t_B - mean(t_B) plot(t_B, B_)
Python 实现代码
import numpy as np from scipy.signal import chirp, correlate import matplotlib.pyplot as plt Fs_=40175 t_max=10 t0_new=np.arange(0, t_max, 1/Fs_) s0_new=chirp(t0_new, f0=400, t1=t_max, f1=10000) B_new = correlate(data['y'], s0_, mode='full') t_B_new = np.arange(0, (1/Fs)*(B_new.shape[0]), (1/Fs)) t_b_new = t_B_new - np.mean(t_B_new) plt.figure(figsize=(12, 8)) plt.plot(t_b_new[0:B_new.shape[0]], B_new) plt.xlabel('counts') plt.ylabel('level') plt.title('signals') plt.legend() plt.show()
问题现象
Python生成的图像与Matlab生成的图像呈现完全不同的形态。
问题排查与修正建议
两者核心功能一致(均用于计算信号互相关),结果差异源于代码细节错误,具体问题及修正方案如下:
信号长度不匹配
Matlab的t0_=0:(1/Fs_):t_max会生成包含t_max的数组,总长度为Fs_*t_max + 1;而Python的np.arange(0, t_max, 1/Fs_)不包含t_max,长度为Fs_*t_max,导致扫频信号长度不一致,直接影响互相关结果。
修正:Python中改用linspace生成匹配长度的时间轴:t0_new = np.linspace(0, t_max, int(Fs_ * t_max) + 1)变量名引用错误
Python代码中correlate(data['y'], s0_, mode='full')引用了未定义的s0_,实际应使用定义好的s0_new:B_new = correlate(data['y'], s0_new, mode='full')时间轴计算错误
- 误用未定义的
Fs,需统一使用Fs_; - 通过均值偏移时间轴易引入浮点误差,建议直接生成对称时间轴:
n = len(B_new) t_B_new = np.arange(-(n-1)/(2*Fs_), (n-1)/(2*Fs_) + 1/Fs_, 1/Fs_)
- 误用未定义的
绘图细节优化
t_b_new长度与B_new一致,无需切片;- 图例需指定标签,避免空图例:
plt.plot(t_B_new, B_new, label='Cross-correlation') plt.legend()
修正后的Python代码示例
import numpy as np from scipy.signal import chirp, correlate import matplotlib.pyplot as plt Fs_ = 40175 t_max = 10 # 生成与Matlab长度一致的时间轴 t0_new = np.linspace(0, t_max, int(Fs_ * t_max) + 1) s0_new = chirp(t0_new, f0=400, t1=t_max, f1=10000) # 使用正确的信号变量计算互相关 B_new = correlate(data['y'], s0_new, mode='full') # 生成对称的时间轴 n = len(B_new) t_B_new = np.arange(-(n-1)/(2*Fs_), (n-1)/(2*Fs_) + 1/Fs_, 1/Fs_) plt.figure(figsize=(12, 8)) plt.plot(t_B_new, B_new, label='Cross-correlation') plt.xlabel('Time (s)') plt.ylabel('Amplitude') plt.title('Cross-correlation of Signals') plt.legend() plt.show()
内容的提问来源于stack exchange,提问作者catauggie
相关产品推荐
相关产品推荐

