2013-06-05 143 views
3

美好的一天,Matlab滤波器不兼容Python lfilter

我一直在围绕着移植到python的matlab代码,我碰到了这个奇怪的问题。我搜索了一下,但没有发现任何信息表明我做错了什么。

问题的核心是Matlab的滤波器(B,A,数据)(它是内置到MATLAB)比较Python的scipy.signal.lfilter

时产生不同的输出这是问题,在任意粉红噪音信号进行

我有由第三方给我的滤波器系数和他们如下:

a0 = 1 
a1 = -1.69065929318241 
a2 = 0.73248077421585 
b0 = 1.53512485958697 
b1 = -2.69169618940638 
b2 = 1.19839281085285 

在MATLAB我初始化分子/分母如下:

a = [a0 a1 a2]; 
b = [b0 b1 b2]; 

在Python中我不喜欢这样写道:

a = np.array([a0, a1, a2]) 
b = np.array([b0, b1, b2]) 

两个MATLAB/Python读物的信号后,我打印出来的第15个样品,以确保你们知道输入的是相同的

Matlab的:

0.061920166015625 
    -0.050170898437500 
    -0.117370605468750 
    -0.065979003906250 
    -0.013854980468750 
    -0.042663574218750 
    0.107452392578125 
    -0.044006347656250 
    0.115112304687500 
    -0.043457031250000 
    -0.028778076171875 
    -0.128234863281250 
    0.045227050781250 
    -0.091796875000000 
    0.315063476562500 

的Python:

[[ 0.06192017] 
[-0.0501709 ] 
[-0.11737061] 
[-0.065979 ] 
[-0.01385498] 
[-0.04266357] 
[ 0.10745239] 
[-0.04400635] 
[ 0.1151123 ] 
[-0.04345703] 
[-0.02877808] 
[-0.12823486] 
[ 0.04522705] 
[-0.09179688]] 

然后调用过滤功能

Matlab的:

out = filter(b,a,data); 
out(1:15) 

ans = 

    0.095055186160338 
    -0.082982934483728 
    -0.180851002009017 
    -0.090458464750796 
    -0.004794343459254 
    -0.049115794227541 
    0.183660200687651 
    -0.061428954478571 
    0.185550654888710 
    -0.070597744360580 
    -0.044524076275862 
    -0.195036835228527 
    0.082983215098531 
    -0.133175807494538 
    0.499

的Python:

out = lfilter(b,a,data) 
print out[0:14] 

[[ 0.09505519] 
[-0.07701859] 
[-0.18017853] 
[-0.10128601] 
[-0.02126912] 
[-0.06549391] 
[ 0.16495284] 
[-0.06755524] 
[ 0.17671176] 
[-0.06671197] 
[-0.04417794] 
[-0.19685653] 
[ 0.06942917] 
[-0.14091966]] 

额外的信息:

Matlab的R2012a

2。 7.3(默认情况下,2012年4月10日,23点31分26秒)[MSC v.1500 32位(英特尔)〕 - >蟒

1.6.2 - > numpy的

我的问题是这样的: 上午我做错了什么,或者我在scipy软件包中发现了一个基本和基本功能的错误?

国王的问候,

ķ

编辑:在下面的意见是建议冲动地给它(我不停的coeffs) Matlab的:

1.535124676585826 
    -0.096323067867721 
    -0.088906133468550 
    -0.079755185442926 
    -0.069716811972987 
    -0.059448236072219 
    -0.049440488368964 
    -0.040042331136521 
    -0.031483732058538 
    -0.023898026476545 
    -0.017342192117849 
    -0.011814893332425 
    -0.007272136901341 
    -0.003640523618135 
    -0.000828184619352 

的Python:

[[ 1.53512468] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ] 
[ 0.  ]] 

这里肯定出了问题, s看起来不像过滤器......

+0

Numpy不是Matlab,也许他们做了不同的事情(因为他们不声称是等同的)? –

+1

这两个函数的文档都意味着它们应该做同样的事情。它们都是直接形式II转置实现 http://www.mathworks.nl/help/matlab/ref/filter.html http://docs.scipy.org/doc/scipy/reference/generated/scipy。 signal.lfilter.html#scipy.signal.lfilter – kbroos

+0

嗯......数学与Matlab相同(http://www.mathworks.com/help/matlab/ref/filter.html#f83-1015962)和Scipy (http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.lfilter.html#scipy.signal.lfilter)。差异太大而不能舍入错误,或浮动vs双倍。如果你给它一个简单的脉冲信号(除了一个单一的1.0以外的所有零)并且让a和b一样简单 - 除了单个1(注意a0必须是1)之外全部为零?真正简单的测试案例可能会揭示一些事情 – DarenW

回答

8

这不是一个错误。 Matlab的filter操作第一个尺寸的阵列,而scipy.signal.lfilter默认操作上一个尺寸。

从你的问题我看到你的data数组有第二维(也许是空的?)。当你使用lfilter时,它默认为axis=-1,它会给你python的答案。如果你想MATLAB的相同的行为,你需要指定第一轴或挤压阵列(如果第二个维度的大小为1):

out = lfilter(b, a, data, axis=0) 
out = lfilter(b, a, np.squeeze(data)) 

这两个返回如下:

[ 0.09505519 
-0.08298293 
-0.180851 
-0.09045846 
-0.00479434 
-0.04911579 
    0.1836602 
-0.06142895 
    0.18555065 
-0.07059774 
-0.04452408 
-0.19503684 
    0.08298322 
-0.13317581 
    0.499] 
+1

这工作,谢谢! – kbroos