2012-10-23 3 views
0

필자는 행렬 연산을 수행하는 곳에 칼만 필터를 구현했습니다. 어떤 점에서 두 개의 1x1 행렬을 빼야합니다. 나는 그것이 어디서 오는지 알지 못하는 오류가있다. 파이썬에서 행렬 연산을 수행하는 가장 좋은 방법은 무엇입니까?파이썬에서 행렬 빼기/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 인스턴스와 행렬을 빼내려고합니다. 행렬 및 행렬이 아닙니다. GetPos의 인스턴스에서

TestDvKalman
+0

감사합니다. 그건 맞지만 어떻게해야합니까. 'DvKalman'을 호출 할 때마다 GetPos에서 새로운 변수 'z'를 얻고 싶습니다. – tomasz74

2

이 줄

z = GetPos() 

세트 z. 이 라인에서 kal에 인수로 사용 :

[position, velocity] = kal(z) 

그렇게 DvKalman__call__ 방법을 사용하면 self.z으로 저장 GetPos의 인스턴스를, 주어진다. 즉,이 줄에서 오류가 발생합니다 :

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

감사합니다. 나는 그런 식으로하려고하지만''GetPos .__ call__'에서'm'이 반환되는'z = [[m]]'을 원합니다. 이것이 어떻게 작동하는지 이해합니다. 나는 무엇을 놓치나요? – tomasz74

+1

GetPos()는 GetPos의 인스턴스를 만듭니다. 그런 다음 GetPos()가 반환 한 객체를 * 호출해야합니다. z를 만들 때 그렇게하든 DvKalman에서'__call__' 메서드로 수행하든 상관없이 모든 작업을 원하는 방식에 달려 있습니다. –