Wholesale changes to connect chapters together.

I made a lot of changes so that each chapter makes clear that
they are all implementing the same basic bayesian algorithm.

This required a lot of editting, and it doesn't make sense to
try to do that atomically, hence this huge check in.

I made a lot of edits, and haven't copy editted anything. i'm
sure I introduced a lot of problems and discontinuities.
This commit is contained in:
Roger Labbe 2015-06-20 15:52:16 -07:00
parent 5ffe5c67eb
commit 51c9a8283e
14 changed files with 2072 additions and 1648 deletions

View File

@ -570,7 +570,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.4.3"
"version": "3.4.1"
}
},
"nbformat": 4,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
"""
Created on Sun May 11 13:21:39 2014
@author: rlabbe
"""
from __future__ import print_function, division
import numpy.random as random
import math
class DogSensor(object):
def __init__(self, x0=0, velocity=1, noise_var=0.0):
""" x0 - initial position
velocity - (+=right, -=left)
noise_var - noise variance, 0== no noise
"""
self.x = x0
self.velocity = velocity
self.noise = math.sqrt(noise_var)
def sense(self):
self.x = self.x + self.velocity
return self.x + random.randn() * self.noise

44
code/DogSimulation.py Normal file
View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
"""
Created on Sun May 11 13:21:39 2014
@author: rlabbe
"""
from __future__ import print_function, division
from numpy.random import randn
import math
class DogSimulation(object):
def __init__(self, x0=0, velocity=1,
measurement_variance=0.0, process_variance=0.0):
""" x0 - initial position
velocity - (+=right, -=left)
measurement_variance - variance in measurement m^2
process_variance - variance in process (m/s)^2
"""
self.x = x0
self.velocity = velocity
self.measurement_noise = math.sqrt(measurement_variance)
self.process_noise = math.sqrt(process_variance)
def move(self, dt=1.0):
'''Compute new position of the dog assuming `dt` seconds have
passed since the last update.'''
# compute new position based on velocity. Add in some
# process noise
velocity = self.velocity + randn() * self.process_noise
self.x += velocity * dt
def sense_position(self):
# simulate measuring the position with noise
measurement = self.x + randn() * self.measurement_noise
return measurement
def move_and_sense(self, dt=1.0):
self.move(dt)
return self.sense_position()

View File

@ -12,30 +12,56 @@ from mpl_toolkits.mplot3d import Axes3D
from numpy.random import multivariate_normal
import stats
def show_residual_chart():
plt.xlim([0.9,2.5])
plt.ylim([1.5,3.5])
plt.scatter ([1,2,2],[2,3,2.3])
plt.scatter ([2],[2.8],marker='o')
ax = plt.axes()
ax.annotate('', xy=(2,3), xytext=(1,2),
def show_residual_chart():
est_y = ((164.2-158)*.8 + 158)
ax = plt.axes(xticks=[], yticks=[], frameon=False)
ax.annotate('', xy=[1,159], xytext=[0,158],
arrowprops=dict(arrowstyle='->',
ec='r', lw=3, shrinkA=6, shrinkB=5))
ax.annotate('', xy=[1,159], xytext=[1,164.2],
arrowprops=dict(arrowstyle='-',
ec='k', lw=1, shrinkA=8, shrinkB=8))
ax.annotate('', xy=(1., est_y), xytext=(0.9, est_y),
arrowprops=dict(arrowstyle='->', ec='#004080',
lw=2,
shrinkA=3, shrinkB=4))
ax.annotate('prediction', xy=(2.04,3.), color='#004080')
ax.annotate('measurement', xy=(2.05, 2.28))
ax.annotate('prior estimate', xy=(1, 1.9))
ax.annotate('residual', xy=(2.04,2.6), color='#e24a33')
ax.annotate('new estimate', xy=(2,2.8),xytext=(2.1,2.8),
arrowprops=dict(arrowstyle='->', ec="k", shrinkA=3, shrinkB=4))
ax.annotate('', xy=(2,3), xytext=(2,2.3),
arrowprops=dict(arrowstyle="-",
ec="#e24a33",
lw=2,
shrinkA=5, shrinkB=5))
plt.title("Kalman Filter Predict and Update")
plt.axis('equal')
plt.scatter ([0,1], [158.0,est_y], c='k',s=128)
plt.scatter ([1], [164.2], c='b',s=128)
plt.scatter ([1], [159], c='r', s=128)
plt.text (1.0, 158.8, "prediction ($x_t)$", ha='center',va='top',fontsize=18,color='red')
plt.text (1.0, 164.4, "measurement ($z$)",ha='center',va='bottom',fontsize=18,color='blue')
plt.text (0, 157.8, "prior estimate ($\hat{x}_{t-1}$)", ha='center', va='top',fontsize=18)
plt.text (1.02, est_y-1.5, "residual", ha='left', va='center',fontsize=18)
plt.text (0.9, est_y, "new estimate ($\hat{x}_{t}$)", ha='right', va='center',fontsize=18)
plt.xlabel('time')
ax.yaxis.set_label_position("right")
plt.ylabel('state')
plt.xlim(-0.5, 1.5)
plt.show()
def plot_gaussian_multiply():
xs = np.arange(-5, 10, 0.1)
mean1, var1 = 0, 5
mean2, var2 = 5, 1
mean, var = stats.mul(mean1, var1, mean2, var2)
ys = [stats.gaussian(x, mean1, var1) for x in xs]
plt.plot(xs, ys, label='M1')
ys = [stats.gaussian(x, mean2, var2) for x in xs]
plt.plot(xs, ys, label='M2')
ys = [stats.gaussian(x, mean, var) for x in xs]
plt.plot(xs, ys, label='M1 x M2')
plt.legend()
plt.show()
@ -329,6 +355,61 @@ def plot_correlation_covariance():
plt.show()
import book_plots as bp
def plot_track(ps, zs, cov,
plot_P=True, y_lim=None,
title='Kalman Filter'):
count = len(zs)
actual = np.linspace(0, count - 1, count)
cov = np.asarray(cov)
std = np.sqrt(cov[:,0,0])
std_top = np.minimum(actual+std, [count + 10])
std_btm = np.maximum(actual-std, [-50])
std_top = actual+std
std_btm = actual-std
bp.plot_track(actual)
bp.plot_measurements(range(1, count + 1), zs)
bp.plot_filter(range(1, count + 1), ps)
plt.plot(std_top, linestyle=':', color='k', lw=2)
plt.plot(std_btm, linestyle=':', color='k', lw=2)
plt.fill_between(range(len(std_top)), std_top, std_btm,
facecolor='yellow', alpha=0.2, interpolate=True)
plt.legend(loc=4)
if y_lim is not None:
plt.ylim(y_lim)
else:
plt.ylim((-50, count + 10))
plt.xlim((0,count))
plt.title(title)
plt.show()
if plot_P:
ax = plt.subplot(121)
ax.set_title("$\sigma^2_x$")
plot_covariance(cov, (0, 0))
ax = plt.subplot(122)
ax.set_title("$\sigma^2_y$")
plot_covariance(cov, (1, 1))
plt.show()
def plot_covariance(P, index=(0, 0)):
ps = []
for p in P:
ps.append(p[index[0], index[1]])
plt.plot(ps)
def test_fill():
plt.fill_between([0,1,2,3,4], [1,1,1,1,1], [4,4,4,4,4])
plt.plot([0,6], [6,1])
# plt.ylim(2,5)
plt.show()
if __name__ == "__main__":
#show_position_chart()
#plot_3d_covariance((2,7), np.array([[8.,0],[0,4.]]))
@ -336,5 +417,6 @@ if __name__ == "__main__":
#show_residual_chart()
#show_position_chart()
show_x_error_chart(4)
#show_x_error_chart(4)
test_fill()

View File

@ -22,14 +22,10 @@ def plot_nonlinear_func(data, f, gaussian, num_bins=300):
#b = f(x) - x*m
# compute new mean and variance based on EKF equations
ys = f(data)
x0 = gaussian[0]
in_std = np.sqrt(gaussian[1])
y = f(x0)
#m = np.mean(ys)
std = np.std(ys)
in_lims = [x0-in_std*3, x0+in_std*3]
@ -40,7 +36,6 @@ def plot_nonlinear_func(data, f, gaussian, num_bins=300):
h = np.histogram(ys, num_bins, density=False)
plt.subplot(2,2,4)
plt.plot(h[0], h[1][1:], lw=4, alpha=0.5)
print(max(h[0]))
plt.ylim(out_lims[1], out_lims[0])
plt.gca().xaxis.set_ticklabels([])
plt.title('output')
@ -58,8 +53,6 @@ def plot_nonlinear_func(data, f, gaussian, num_bins=300):
plt.plot(pdf * max(h[0])/max(pdf), xs, lw=1, color='k')
print(max(norm.pdf(xs)))'''
# plot transfer function
plt.subplot(2,2,3)
x = np.arange(in_lims[0], in_lims[1], 0.1)
@ -82,7 +75,6 @@ def plot_nonlinear_func(data, f, gaussian, num_bins=300):
plt.title('input')
plt.show()
print("fuck")
import math

25
experiments/test1d.py Normal file
View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
Created on Thu Jun 18 09:16:54 2015
@author: rlabbe
"""
from filterpy.kalman import KalmanFilter
kf = KalmanFilter(1, 1)
kf.x[0,0] = 1.
kf.P = np.ones((1,1))
kf.H = np.array([[2.]])
kf.F = np.ones((1,1))
kf.R = 1
kf.Q = 0
kf.predict()
kf.update(2)