Selesnick教授DWT的MATLAB实现转Python时索引越界问题求助
问题核心原因
- 第一个错误:
scipy.signal.upfirdn与 MATLABupfirdn的参数顺序相反
MATLAB调用格式为upfirdn(x, h, up, down),scipy调用格式为upfirdn(h, x, up, down),你之前把滤波器和输入信号的顺序写反了,导致输出的lo/hi长度不符合预期,触发索引越界。 - 第二个错误:冗余的索引写法容易触发边界错误,MATLAB为1基索引,Python numpy为0基索引,直接用切片写法更简洁安全,不需要额外拼接数组。
- 第三个隐藏问题:MATLAB的
length(af)取的是数组的最大维度长度,对应Python中af.shape[0](因为af为M行2列的滤波器矩阵),需确认L的计算逻辑正确。
正确的Python实现代码
首先导入依赖:
import numpy as np from scipy.signal import upfirdn
完整的afb函数实现:
def afb(x, af): """ 分析滤波器组 参数: x: N点向量(N为偶数),长度需至少为滤波器长度的2倍 af: 分析滤波器矩阵,af[:,0]为低通滤波器(偶长度),af[:,1]为高通滤波器(偶长度) 返回: lo: 低频分量 hi: 高频分量 """ N = len(x) filter_len = af.shape[0] L = filter_len // 2 # 对应MATLAB的cshift(x,-L),循环左移L位 x = np.roll(x, -L) # 低通滤波,注意scipy的upfirdn参数顺序是h在前,x在后 lo = upfirdn(af[:, 0], x, 1, 2) # 对应MATLAB的lo(1:L) = lo(N/2+[1:L]) + lo(1:L) lo[:L] = lo[N//2 : N//2 + L] + lo[:L] lo = lo[:N//2] # 高通滤波 hi = upfirdn(af[:, 1], x, 1, 2) hi[:L] = hi[N//2 : N//2 + L] + hi[:L] hi = hi[:N//2] return lo, hi
验证说明
你输入长度为10000的x时,N//2=5000,upfirdn输出的lo长度为(10000 + filter_len -1) // 2 = 5000 + L,因此N//2 : N//2 + L的索引范围是5000到5000+L-1,刚好落在lo的合法索引区间内,不会出现越界报错。
内容的提问来源于stack exchange,提问作者Nice Guy
相关产品推荐
相关产品推荐

