简体   繁体   English

使用 python 评估过滤器 matlab function

[英]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=-1lfilter应用于该输入应用过滤器 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM