我在搞乱 IIR/FIR 滤波器,想将前者转换为后者。
我建立了一个经典的脉冲响应计算。
X[4] = 1.0 Y[0] = 0.0 Y[1] = 0.0 对于范围内的n(2,L): Y[n] = 0.5 * X[n] + 0.3 * X[n-1] + 0.2 * Y[n-1] + 0.1 * Y[n-2]
并且(向 Dan B 和 Matt L 大喊)使用 scipy “lfilter” 和 “dimpulse” 函数。当使用零的初始值时,它们匹配。
Y2 = sig.lfilter( [ 0.5 , 0.3 ], [ 1, -0.2, -0.1], X ) T3, Y3 = sig.dimpulse( ( [ 0.5 , 0.3 ], [ 1, -0.2, -0.1], 1 ) ) 对于范围内的n(20): 打印(“%4d %10.5f %10.5f %10.5f”%\ (n, Y3[0][n].real, Y2[n].real, Y[n].real))
这是价值观。
0 0.00000 0.00000 0.00000 1 0.50000 0.00000 0.00000 2 0.40000 0.00000 0.00000 3 0.13000 0.00000 0.00000 4 0.06600 0.50000 0.50000 5 0.02620 0.40000 0.40000 6 0.01184 0.13000 0.13000 7 0.00499 0.06600 0.06600 8 0.00218 0.02620 0.02620 9 0.00094 0.01184 0.01184 10 0.00041 0.00499 0.00499 11 0.00017 0.00218 0.00218 12 0.00008 0.00094 0.00094 13 0.00003 0.00041 0.00041 14 0.00001 0.00017 0.00017 15 0.00001 0.00008 0.00008 16 0.00000 0.00003 0.00003 17 0.00000 0.00001 0.00001 18 0.00000 0.00001 0.00001 19 0.00000 0.00000 0.00000
直接获得 FIR 系数的明显方法是进行多项式除法。
所以我做了一些搜索并找到了numpy.polydiv( B, A )
,但很失望它没有按照我想要的方式工作。它停在“整数”而不是“计算小数部分”。
我写了一个例程来做到这一点(包括在这里是为了其他人的利益)。
将 numpy 导入为 np #=================================================== ============================== 定义主(): B = np.array( [ 0.5 , 0.3 ] ) A = np.array( [ 1, -0.2, -0.1] ) 打印(乙) 打印(一) Q, R = 除法多项式(B, A, 15) 打印(问) 打印(R) #=================================================== ============================== def DividePolynomials(ArgNum,ArgDen,ArgLength): Q = np.zeros(ArgLength * 2, dtype=complex) R = np.zeros(ArgLength * 2,dtype=complex) S = np.zeros(ArgLength * 2, dtype=complex) R[0:len(ArgNum)] = ArgNum 对于范围内的 d(ArgLength): rd = R[d] / ArgDen[0] Q[d] = rd S.fill(0.0) S[d:d+len(ArgDen)] = rd * ArgDen R -= S 返回 Q[0:ArgLength], R[ArgLength:] #=================================================== ============================== 主要的()
这是输出:
[ 0.5 0.3] [ 1. -0.2 -0.1] [ 5.00000000e-01+0.j 4.00000000e-01+0.j 1.30000000e-01+0.j 6.60000000e-02+0.j 2.62000000e-02+0.j 1.18400000e-02+0.j 4.98800000e-03+0.j 2.18160000e-03+0.j 9.35120000e-04+0.j 4.05184000e-04+0.j 1.74548800e-04+0.j 7.54281600e-05+0.j 3.25405120e-05+0.j 1.40509184e-05+0.j 6.06423488e-06+0.j] [ 2.61793882e-06+0.j 6.06423488e-07+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j]
系数与来自脉冲分析的预期值很好地匹配,其余的让我了解它的收敛程度。
当然,我做了一些搜索,发现了这个:
在链接的问题中,选择的答案涉及曲线拟合,其他答案与我的预期一致。但是,添加您希望保持过滤器阶数较低的条件,当然可以比截断的多项式更好地拟合多项式. 我没有遵循论文参考。IEEE 论文通常在一些付费墙后面。但我认为这与我们在这里遇到的相同的数学问题“什么是最适合的多项式”从到" 与商扮演泰勒级数的角色。
问题 1:我在 numpy/scipy 中是否有一个多项式除法函数可以满足我的要求。[已解决:见 Olli 的回答]
问题 2:在“现实生活”中,典型 IIR 到 FIR 转换的典型 FIR 长度是多少,这个额外的多项式拟合步骤通常需要/有益吗?
我意识到在我的示例中,我正在处理一个很小的、表现良好的 IIR。