Skip to content

Commit

Permalink
Issue rlabbe#51. Wrong weights in UKF RTS smoother.
Browse files Browse the repository at this point in the history
The code used the mean weights in the computation for the covariances,
when obviously the covariance weights should be used.
  • Loading branch information
rlabbe committed Sep 20, 2016
1 parent 4051e83 commit 10f50dc
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
4 changes: 2 additions & 2 deletions filterpy/kalman/UKF.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,15 +516,15 @@ def rts_smoother(self, Xs, Ps, Qs=None, dt=None):
x = Xs[k]
for i in range(num_sigmas):
y = sigmas_f[i] - x
Pb += self.Wm[i] * outer(y, y)
Pb += self.Wc[i] * outer(y, y)
Pb += Qs[k]

# compute cross variance
Pxb = 0
for i in range(num_sigmas):
z = sigmas[i] - Xs[k]
y = sigmas_f[i] - xb
Pxb += self.Wm[i] * outer(z, y)
Pxb += self.Wc[i] * outer(z, y)

# compute gain
K = dot(Pxb, inv(Pb))
Expand Down
51 changes: 45 additions & 6 deletions filterpy/kalman/tests/test_ukf.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
from math import cos, sin




DO_PLOT = False


Expand Down Expand Up @@ -240,7 +242,7 @@ def hx(x):
plt.plot(t, xs[:,2])


def test_linear_2d():
def test_linear_2d_merwe():
""" should work like a linear KF if problem is linear """


Expand All @@ -257,8 +259,7 @@ def hx(x):


dt = 0.1
# points = MerweScaledSigmaPoints(4, .1, 2., -1)
points = SimplexSigmaPoints(n=4)
points = MerweScaledSigmaPoints(4, .1, 2., -1)
kf = UKF(dim_x=4, dim_z=2, dt=dt, fx=fx, hx=hx, points=points)


Expand All @@ -272,7 +273,48 @@ def hx(x):
z = np.array([i+randn()*0.1, i+randn()*0.1])
zs.append(z)

Ms, Ps = kf.batch_filter(zs)
smooth_x, _, _ = kf.rts_smoother(Ms, Ps, dt=dt)

if DO_PLOT:
plt.figure()
zs = np.asarray(zs)
plt.plot(zs[:,0], marker='+')
plt.plot(Ms[:,0], c='b')
plt.plot(smooth_x[:,0], smooth_x[:,2], c='r')
print(smooth_x)


def test_linear_2d_simplex():
""" should work like a linear KF if problem is linear """


def fx(x, dt):
F = np.array([[1, dt, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, dt],
[0, 0, 0, 1]], dtype=float)

return np.dot(F, x)

def hx(x):
return np.array([x[0], x[2]])


dt = 0.1
points = SimplexSigmaPoints(n=4)
kf = UKF(dim_x=4, dim_z=2, dt=dt, fx=fx, hx=hx, points=points)


kf.x = np.array([-1., 1., -1., 1])
kf.P*=0.0001
#kf.R *=0
#kf.Q

zs = []
for i in range(20):
z = np.array([i+randn()*0.1, i+randn()*0.1])
zs.append(z)

Ms, Ps = kf.batch_filter(zs)
smooth_x, _, _ = kf.rts_smoother(Ms, Ps, dt=dt)
Expand All @@ -286,8 +328,6 @@ def hx(x):

print(smooth_x)



def test_linear_1d():
""" should work like a linear KF if problem is linear """

Expand Down Expand Up @@ -329,7 +369,6 @@ def hx(x):




def test_batch_missing_data():
""" batch filter should accept missing data with None in the measurements """

Expand Down

0 comments on commit 10f50dc

Please sign in to comment.