2012-10-23 143 views
0

我有一个卡尔曼滤波器的实现,我正在做矩阵运算。在某些时候,我应该减去两个1x1矩阵。我有一个错误,我不知道它是从哪里来的。 在python中做矩阵运算的最好方法是什么?python/numpy中的矩阵相减

import numpy as np 
import pylab as pl 
import scipy as Sci 
import scipy.linalg as linalg 

class GetPos(object): 
    def __init__(self): 
     self.Posp = 0 
     self.Velp = 80 
     self.z = np.matrix(0) 
    def __repr__(self): 
     return "from GetPos.__repr__ z=%s" % (self.z) 
    def __call__(self): 
     self.dt = 0.1 
     self.w = 0 + 10*np.random.random() 
     self.v = 0 + 10*np.random.random()    
     self.z = self.Posp + self.Velp*self.dt + self.v 
     self.Posp = self.z - self.v 
     self.Velp = 80 + self.w 
     print 'from GetPos.__call__ z = %s' % self.z 
     return self.z 

class DvKalman(object): 
    def __init__(self): 
     self.dt = .1 
     self.A = np.matrix([[1., self.dt],[0,1]]) 
     self.H = np.matrix([1., 0]) 
     self.Q = np.matrix([[1,0.],[0,3]]) 
     self.R = np.matrix(10) 
     self.x = np.matrix([0,20]).T 
     self.P = np.matrix(5*np.eye(2)) 
     #print 'P matrix \n%s' % self.P 
     self.firstRun = 0 
    def __call__(self, z): 
     self.z = z 
     print 'from DvKalman.__call__ slef.z = %s and z = %s' % (self.z,z) 
     self.xp = self.A * self.x 
     self.Pp = self.A*self.P*self.A.T + self.Q 
     self.K = self.Pp * self.H.T * linalg.inv(np.absolute(self.H*self.Pp*self.H.T + self.R)); 
     print 'from DvKalman.__call__ z=%s, \npreviouse x=\n%s \nH = \n%s \nand P=\n%s \nand xp=\n%s,\n Pp = \n%s,\n K=\n%s' % (self.z,self.x,self.H, self.P,self.xp,self.Pp,self.K) 
     newM1 = self.H*self.xp  
     print 'This is self.H*self.xp %s and this is self.z = %s' % (newM1, self.z) 
     newM2 = self.z - self.H*self.xp 
     print 'This should give simple substruction %s' % newM2     
     self.x = self.xp + self.K*(self.z - self.H*self.xp) 
     self.P = self.Pp - self.K*self.H*self.Pp 
     print 'new values x=%s and P=%s' % (self.x,self.P) 
     return (self.x) 
def TestDvKalman(): 
    Nsamples = np.arange(0,10,.1) 

    kal = DvKalman() 
    #print type(kal) 
    Xsaved = [] 
    Zsaved = [] 

    for i in range(len(Nsamples)): 
     z = GetPos() 
     print z 
     print 'from TestDvKalman zpos = %s' % z 
     Zsaved.append(z) 
     [position, velocity] = kal(z) 
     print position, velocity 
     Xsaved.append([position, velocity]) 
    print Zsaved 
    print Xsaved 
# f1 = pl.subplot(121) 
# f1 = pl.plot(Xsaved, 'x-',label = 'Xsaved') 
# f1 = pl.legend() 
#  
# f2 = pl.subplot(122) 
# f2 = pl.title('Kalman Velocity') 
# f2 = pl.plot(Zsaved, 'o-', color = 'brown',label = 'Zsaved') 
# f2 = pl.legend() 
#  
# pl.show() 

if __name__ == '__main__': 
    TestDvKalman() 

我已经添加了几行print跟踪和调试代码,我增加了新的变数newM这不会是在代码中。矩阵打印正确This is self.H*self.xp [[ 2.]] and this is self.z = from GetPos.__repr__ z=[[0]]这两个矩阵都是1x1,但我仍然收到一个错误,不知道为什么。错误是:

newM2 = self.z - self.H*self.xp 
TypeError: unsupported operand type(s) for -: 'GetPos' and 'matrix' 

我怀疑我搞乱了类型的地方,但不知道在哪里以及如何纠正它。你能指出我的错误在哪里,以及如何构建这样的代码以避免将来出现类似的错误?

回答

1

通过newM2 = self.z() - self.H*self.xp更换newM2 = self.z - self.H*self.xp

该程序应该与那个(但我不能确认它是否会想要你想要)

2

您正在将GetPos实例传递给DvKalman __call__方法。所以你试图减去一个GetPos实例和一个矩阵。不是矩阵和矩阵。

+0

谢谢。这是正确的,但我应该怎么做比。每次我给'DvKalman'打电话时,我都想从'GetPos'得到新的变量'z' – tomasz74

2

TestDvKalman,这条线

z = GetPos() 

z到的GetPos一个实例。您在此行中使用这个作为参数传递给kal

[position, velocity] = kal(z) 

所以DvKalman__call__方法给出的GetPos一个实例,其中保存为self.z。这导致错误在这行:

newM2 = self.z - self.H*self.xp 
+0

谢谢。我打算做这样的事情,但我想''=''[m]]'从'GetPos .__ call__'返回'm'我明白这是它的工作原理。我错过了什么? – tomasz74

+1

GetPos()创建一个GetPos的实例。然后您必须*调用GetPos()返回的对象。无论你在创建z时还是在DvKalman的__call__方法中都这样做,取决于你希望如何工作。 –