尺寸不匹配:数组' cov'形状(1,1),但意思是'是一个长度为2的向量

时间:2015-11-26 04:10:37

标签: python-3.x numpy scipy kalman-filter

我试图执行以下代码

p, c = [], []
for z in mes:
    print (z)
    print (c)
    print (p)
    p.append(kf.x)
    c.append(kf.P)
    kf.predict()
    kf.update(z) #error on this line

我收到错误:

  

ValueError:尺寸不匹配:数组' cov'形状(1,1),但   '平均'是一个长度为2的向量。

这是屏幕上显示的输出

[512  102]
[array([[ 1000.,     0.,     0.,     0.],
       [    0.,  1000.,     0.,     0.],
       [    0.,     0.,  1000.,     0.],
       [    0.,     0.,     0.,  1000.]])]
[array([[ 396.],
       [  187.],
       [    0.],
       [    0.]])]

如果我只采用z的第一个元素,它可以正常工作,但是,这并不是我想要的行为。

p, c = [], []
for z in mes:
    print (z)
    print (c)
    print (p)
    p.append(kf.x)
    c.append(kf.P)
    kf.predict()
    kf.update(z[0]) 

更新其他信息

此错误来自multivariate.py in scipy。我似乎无法从cov更改(1,1)的形状。我可以使用mean更改z[0]的长度,但是,这并不合适。我想原样使用z。我还将整个代码发布为gist here。我也将filterpy library用于卡尔曼滤波器。有live python notebook使用此卡尔曼过滤器,但是,它并没有像我的场景中那样使用z

1 个答案:

答案 0 :(得分:1)

使用filterpy库时,您自己负责设置卡尔曼滤波器的初始状态,并且各种矩阵的尺寸需要兼容。如果您查看KalmanFilter.update()方法,您可以跟踪它所执行的计算,并在矩阵维度上提出以下一组约束:

R.shape == (dim_z, dim_z)
H.shape == (dim_z, dim_x)
P.shape == (dim_x, dim_x)
x.shape == (dim_x, 1...)
z.shape == (dim_z, 1...)

其中1...可以表示大小为1的某些维度序列,两者的大小相同。例如,在您的情况下,dim_x == 4dim_z == 2因此您可以拥有x.shape == (4, 1)z.shape == (2, 1),或者您可以拥有x.shape == (4,)z.shape == (2,),但你不能混搭。 (请注意,KalmanFilter.__init__()文档似乎为H提供了错误的必需维度。)

您的代码在两个位置设置了错误的尺寸:

  • 您将H设置为1x4矩阵,而不是2x4。 (我注意到你已经注释了有效的代码。)
  • 您将R设置为标量值而不是2x2矩阵。可以说卡尔曼滤波器实现应该考虑到这一点,但只有当你将R作为参数传递给update()时才会这样做,而不是在你提前设置它时。 (但要小心:如果将R设置为标量,代码仍将工作!它会做我认为错误的事情:为每个元素添加2矩阵而不是添加2倍的单位矩阵。)
  • 当您将z传递给update()方法时,您传递的是一个两元素列表,该列表将转换为2元素向量,而不是2x1矩阵,因为它应该是与x(4x1)兼容。您可以通过在调用z = np.array([z]).T之前在循环体中运行update() 来解决此问题。但我认为有更好的方法:保持z不变,只需将x设为4元素向量:

    x = np.array([measurements[0][0],measurements[0][1],0.,0.])
    

    我不确定这是否意味着作者的工作,但它确实(目前),它可能应该。我认为要求在传递之前将每个测量值转换为2x1矩阵是有点傻。

KalmanFilter包含test_matrix_dimensions()方法,您可以使用该方法检查设置中的错误。但是我对它有点矛盾,因为如果你将x设置为4元素向量,正如我在上一段中所建议的那样,它会将其标记为不正确。