def tracking_example2(): ''' Tracking a brownian motion process ''' from scipy.stats import multivariate_normal as norm #Brownian motion kernel def K_brownian(tx, ty, sigma2): return (sigma2)*np.minimum(tx, ty) def sample_gp(t, cov_func): ''' Draws samples from a gaussian process with covariance given by cov_func. cov_func should be a function of 2 variables e.g. cov_func(tx, ty). For the x,y coordinates of the matrix. If the underlying covariance function requires more than 2 arguments, then they should be passed via a lambda function. ''' tx, ty = np.meshgrid(t, t) cov = cov_func(tx, ty) return norm.rvs(cov = np.array(cov)) np.random.seed(4) N = 800 #Length of data lmbda = 0.99 #Forgetting factor p = 6 #Filter order sd2 = 2 d = sample_gp(range(N), lambda tx, ty: K_brownian(tx, ty, sd2)) #Initialize RLS filter and then #Get function closure implementing 1 step prediction F = RLS(p = p, lmbda = lmbda) ff_fb = one_step_pred_setup(F) #Run it through the filter and get the error d_hat = np.array([0] + [ff_fb(di) for di in d])[:-1] err = (d - d_hat) plt.subplot(2,1,1) plt.plot(range(N), d, linewidth = 2, linestyle = ':', label = 'True Process') plt.plot(range(N), d_hat, linewidth = 2, label = 'Prediction') plt.legend() plt.xlabel('$n$') plt.ylabel('Process Value') plt.title('RLS tracking a process, '\ '$\\lambda = %s$, $p = %d$' % (lmbda, p)) plt.subplot(2,1,2) plt.plot(range(N), err, linewidth = 2) plt.xlabel('$n$') plt.ylabel('Error') plt.title('Prediction Error') plt.show() return
def tracking_example1(): ''' Shows the RLS algorithm tracking a time varying process. ''' np.random.seed(314) N = 500 #Length of data lmbda = 0.99 #Forgetting factor p = 6 #Filter order #Filter for generating d(n) b = [1, -0.5, .3] a = [1, 0.2, 0.16, -0.21, -0.0225] sv2 = .25 #Innovations noise variance #Track a time varying process t = np.linspace(0, 1, N) f = 2 v = 4*np.sin(2*np.pi*f*t) + \ gaussian.rvs(size = N, scale = math.sqrt(sv2)) #Innovations d = lfilter(b, a, v) #Desired process #Initialize RLS filter and then #Get function closure implementing 1 step prediction F = RLS(p = p, lmbda = lmbda) ff_fb = one_step_pred_setup(F) #Run it through the filter and get the error d_hat = np.array([0] + [ff_fb(di) for di in d])[:-1] err = (d - d_hat) plt.subplot(2,1,1) plt.plot(range(N), d, linewidth = 2, linestyle = ':', label = 'True Process') plt.plot(range(N), d_hat, linewidth = 2, label = 'Prediction') plt.legend() plt.xlabel('$n$') plt.ylabel('Process Value') plt.title('RLS tracking a process ' \ '$\\lambda = %s$, $p = %d$' % (lmbda, p)) plt.subplot(2,1,2) plt.plot(range(N), err, linewidth = 2) plt.xlabel('$n$') plt.ylabel('Error') plt.title('Prediction Error') plt.show() return
def tracking_example4(): ''' Shows the RLS algorithm tracking a process with fat tailed noise. We compare performance with and without a clamped input range. Obviously, simply clipping the input range is a pretty naive method for dealing with fat tailed noise. ''' np.random.seed(2718) N = 1000 #Length of data lmbda = 0.98 #Forgetting factor p = 6 #Filter order #Filter for generating d(n) b = [1, -0.5, .3] a = [1, 0.2, 0.16, -0.21, -0.0225] sv2 = .25 #Innovations noise variance beta = 1.25 psv = 0.025 t = np.linspace(0, 1, N) f = 2 v = 2*np.sin(2*np.pi*f*t) + \ gaussian.rvs(size = N, scale = math.sqrt(sv2)) #Innovations d = lfilter(b, a, v) #Desired process d = d + pareto.rvs(beta, size = N, scale = math.sqrt(psv)) #fat tailed noise def clamp(x, M, m): return M*(x >= M) + m*(x <= m) + x*(x < M and x > m) M = 4. m = -4. d_clamp = np.array([clamp(di, M, m) for di in d]) #Initialize RLS filter and then #Get function closure implementing 1 step prediction #-------CLAMPED INPUT----------- F = RLS(p = p, lmbda = lmbda) ff_fb = one_step_pred_setup(F) d_hat_clamp = np.array([0] + [ff_fb(di) for di in d_clamp])[:-1] err_clamp = (d - d_hat_clamp) MSE_avg_clamp = np.average(abs(err_clamp)**2) #--------UNCLAMPED INPUT--------- F = RLS(p = p, lmbda = lmbda) ff_fb = one_step_pred_setup(F) #Run it through the filter and get the error d_hat = np.array([0] + [ff_fb(di) for di in d])[:-1] err = (d - d_hat) MSE_avg = np.average(abs(err)**2) plt.subplot(2,1,1) plt.plot(range(N), d, linewidth = 1, linestyle = ':', label = 'True Process') plt.plot(range(N), d_clamp, linewidth = 1, linestyle = '--', label = 'Clamped Process') plt.plot(range(N), d_hat, linewidth = 1, label = 'Prediction') plt.plot(range(N), d_hat_clamp, linewidth = 1, label = 'Prediction (clamped)') plt.legend() plt.xlabel('$n$') plt.ylabel('Process Value') plt.title('RLS tracking a process ' \ '$\\lambda = %s$, $p = %d$' % (lmbda, p)) plt.subplot(2,1,2) plt.plot(range(N), err, linewidth = 2, label = 'err') plt.plot(range(N), err_clamp, linewidth = 2, label = 'err (clamped)') plt.hlines(MSE_avg, 0, N, linestyle = '--', label = 'MSE', linewidth = 3, color = 'r') plt.hlines(MSE_avg_clamp, 0, N, linestyle = '--', label = 'MSE (clamped)', linewidth = 3, color = 'y') plt.legend() plt.xlabel('$n$') plt.ylabel('Error') plt.title('Prediction Error') plt.show() return
def tracking_example3(): ''' Shows the RLS algorithm tracking a process with time varying statistics. ''' np.random.seed(314) N = 5000 #Length of data lmbda = .98 #Forgetting factor p_RLS = 4 #RLS Filter order #Filter for generating d(n) p1_f = 1.35 #Frequency of pole 1 p2_fA = 1.1 #Frequency of pole 2 amplitude p2_fP = 1.5 #Frequency of pole 2 phase def A(tau, t): a = [1, -0.1, -0.8, 0.2] p1 = 0.25 + 0.75*np.sin(2*np.pi*t*p1_f) #pole 1 position p2A = 0.15 + abs(0.75*np.sin(2*np.pi*t*p2_fA)) #pole 2 amplitude p2P = np.exp(2*np.pi*1j*t*p2_fP) #pole 2 phase p2 = p2A*p2P p3 = p2.conj() #pole 3 a = np.poly([p1, p2, p3]) return -a[tau + 1] b = [1., -.2, 0.8] B = lambda tau, t : b[tau] p = 3 q = 1 sv2 = 0.25 #Scale paremeter #Track a time varying process t = np.linspace(0, 1, N) f = 2 # v = 4*np.sin(2*np.pi*f*t) + \ # gaussian.rvs(size = N, scale = math.sqrt(sv2)) #Innovations v = gaussian.rvs(size = N, scale = math.sqrt(sv2)) # v = pareto.rvs(beta, size = N, scale = math.sqrt(sv2)) # d = lfilter(b, a, v) #Desired process d = tvfilt(B, A, v, p, q, t) #Initialize RLS filter and then #Get function closure implementing 1 step prediction F = RLS(p = p_RLS, lmbda = lmbda) ff_fb = one_step_pred_setup(F) #Run it through the filter and get the error d_hat = np.array([0] + [ff_fb(di) for di in d])[:-1] err = (d - d_hat) plt.subplot(2,1,1) plt.plot(range(N), d, linewidth = 2, linestyle = ':', label = 'True Process') plt.plot(range(N), d_hat, linewidth = 2, label = 'Prediction') plt.legend() plt.xlabel('$n$') plt.ylabel('Process Value') plt.title('RLS tracking a process ' \ '$\\lambda = %s$, $p = %d$' % (lmbda, p)) plt.subplot(2,1,2) plt.plot(range(N), err, linewidth = 2) plt.xlabel('$n$') plt.ylabel('Error') plt.title('Prediction Error') plt.show() F = RLS(p = p_RLS, lmbda = lmbda) ff_fb = system_identification_setup(F) w_hat = np.array([ff_fb(di) for di in d]) a1 = np.array([A(0, ti) for ti in t]) a2 = np.array([A(1, ti) for ti in t]) a3 = np.array([A(2, ti) for ti in t]) plt.plot(t, a1, linestyle = '--', label = '$a[1]$') plt.plot(t, a2, linestyle = '--', label = '$a[2]$') plt.plot(t, a3, linestyle = '--', label = '$a[3]$') plt.plot(t, w_hat[:, 0], label = '$w[0]$') plt.plot(t, w_hat[:, 1], label = '$w[1]$') plt.plot(t, w_hat[:, 2], label = '$w[2]$') plt.plot(t, w_hat[:, 3], label = '$w[3]$') plt.legend() plt.title('RLS Tracking ARMA Process, misspecified $p$') plt.show() return