[英]Evaluate filter matlab function using python
Based on the description of both functions, filter(b, a, x)
matlab function and lfilter(b, a, x, axis=-1, z_i=None)
scipy.signal should give the same result.根据这两个函数的描述, filter(b, a, x)
matlab function 和lfilter(b, a, x, axis=-1, z_i=None)
scipy.signal 应该给出相同的结果。
I take this example where the results are completely different:我举这个例子,结果完全不同:
import numpy as np
from scipy.signal import lfilter
bb = np.arange(0, 100, 1)
aa = 1
xx = np.tile(0.9, (100, 1))
yy = lfilter(b=bb, a=aa, x=xx)
print(yy[:10])
array([[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.]])
print(yy.shape)
(100, 1)
# Same example on Matlab using filter
bb = 0:1:99
aa = 1
xx =repmat(0.9, 100, 1)
dd = filter(bb, aa, xx)
dd(1:10)
ans =
0
0.9000
2.7000
5.4000
9.0000
13.5000
18.9000
25.2000
32.4000
40.5000
print(size(dd)) # (100 ,1)
MATLAB and NumPy handle array shapes differently. MATLAB 和 NumPy 处理数组形状的方式不同。 NumPy has general n-dimensional arrays. scipy.signal.lfilter
accepts an n-dimensional array, and applies the filter along each 1-d slice of the input array. NumPy 具有一般 n 维scipy.signal.lfilter
接受一个 n 维数组,并沿输入数组的每个一维切片应用过滤器。 Which slice is determined by the axis
parameter.哪个切片由axis
参数决定。 By default, lfilter
operates on the last axis ( axis=-1
).默认情况下, lfilter
在最后一个轴 ( axis=-1
) 上运行。 You gave lfilter
an array with shape (100, 1).你给了lfilter
一个形状为 (100, 1) 的数组。 Applying lfilter
with axis=-1
to that input applies the filter 100 times, once for each row of length 1--certainly not what you want, Instead, you want to apply the filter along axis=0
(which in this 2-d case, means apply lfilter
along the columns).将带有axis=-1
的lfilter
应用于该输入应用过滤器 100 次,每行长度为 1 一次——当然不是你想要的,相反,你想沿axis=0
应用过滤器(在这个 2-d情况下,意味着沿列应用lfilter
)。 If you change the call of lfilter
to如果将lfilter
的调用更改为
yy = lfilter(b=bb, a=aa, x=xx, axis=0)
the values returned will match those of the MATLAB code.返回的值将匹配 MATLAB 代码的值。
In the long term, I recommend not limiting yourself to 2-d arrays. In this case, it makes more sense to create xx
as a 1-d array (eg xx = np.full(100, fill_value=0.9)
).从长远来看,我建议不要将自己局限于二维 arrays。在这种情况下,将xx
创建为一维数组更有意义(例如xx = np.full(100, fill_value=0.9)
)。 Then lfilter
will operate on the given 1-d array the way you expect, without having to specify the axis
.然后lfilter
将按照您期望的方式对给定的一维数组进行操作,而无需指定axis
。
The answer of @warren is good. @warren 的回答很好。 Here are more details about the use of functions.这里有更多关于函数使用的细节。
filter(b, a, x, zi, dim)
return zf
value even if zi
is not given as input. filter(b, a, x, zi, dim)
返回zf
值,即使zi
没有作为输入给出。
In the example above:在上面的例子中:
[y, zf] = filter(b=bb, a=aa, x=xx)
zf(1:10)
ans =
1.0e+03 *
4.4550
4.4541
4.4523
4.4496
4.4460
4.4415
4.4361
4.4298
4.4226
4.4145
However in lfilter(a, b, x, zi=None, axis=-1)
, to get the zf
, you have to provide zi
.但是在lfilter(a, b, x, zi=None, axis=-1)
中,要获得zf
,您必须提供zi
。 For that, you can use, lfilter_zi(b, x)
that construct initial conditions for lfilter
for step response steady-state.为此,您可以使用lfilter_zi(b, x)
为lfilter
构建阶跃响应稳态的初始条件。
z_i = lfilter_zi(b=bb, a=aa)
y, zf = lfilter(b=bb, x=xx, a=aa, zi=z_i, axis=0)
zf[1:10]
[[4455. ]
[4454.1]
[4452.3]
[4449.6]
[4446. ]
[4441.5]
[4436.1]
[4429.8]
[4422.6]
[4414.5]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.