-
Notifications
You must be signed in to change notification settings - Fork 0
/
0205.py
89 lines (81 loc) · 2.58 KB
/
0205.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# -*- coding: utf-8 -*-
"""
Created on Mon Sep 24 15:45:04 2018
Kalman Filter: Formal
@author: Yizhen Zhao
"""
import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt
def Kalman_Filter(Y):
S = Y.shape[0]
S = S + 1
"Initialize Params:"
Z = param0[0]
T = param0[1]
H = param0[2]
Q = param0[3]
"Kalman Filter Starts:"
u_predict = np.zeros(S)
u_update = np.zeros(S)
P_predict = np.zeros(S)
P_update = np.zeros(S)
v = np.zeros(S)
F = np.zeros(S)
KF_Dens = np.zeros(S)
for s in range(1,S):
if s == 1:
P_update[s] = 1000
P_predict[s] = T*P_update[1]*np.transpose(T)+Q
else:
F[s] = Z*P_predict[s-1]*np.transpose(Z)+H
v[s]=Y[s-1]-Z*u_predict[s-1]
u_update[s] = u_predict[s-1]+P_predict[s-1]*np.transpose(Z)*(1/F[s])*v[s]
u_predict[s] = T*u_update[s];
P_update[s] = P_predict[s-1]-P_predict[s-1]*np.transpose(Z)*(1/F[s])*Z*P_predict[s-1];
P_predict[s] = T*P_update[s]*np.transpose(T)+Q
KF_Dens[s] = (1/2)*np.log(2*np.pi)+(1/2)*np.log(abs(F[s]))+(1/2)*np.transpose(v[s])*(1/F[s])*v[s]
Likelihood = np.sum(KF_Dens[1:-1])
return Likelihood
def Kalman_Smoother(params, Y):
S = Y.shape[0]
S = S + 1
"Initialize Params:"
Z = params[0]
T = params[1]
H = params[2]
Q = params[3]
"Kalman Filter Starts:"
u_predict = np.zeros(S)
u_update = np.zeros(S)
P_predict = np.zeros(S)
P_update = np.zeros(S)
v = np.zeros(S)
F = np.zeros(S)
for s in range(1,S):
if s == 1:
P_update[s] = 1000
P_predict[s] = T*P_update[1]*np.transpose(T)+Q
else:
F[s] = Z*P_predict[s-1]*np.transpose(Z)+H
v[s]=Y[s-1]-Z*u_predict[s-1]
u_update[s] = u_predict[s-1]+P_predict[s-1]*np.transpose(Z)*(1/F[s])*v[s]
u_predict[s] = T*u_update[s];
P_update[s] = P_predict[s-1]-P_predict[s-1]*np.transpose(Z)*(1/F[s])*Z*P_predict[s-1];
P_predict[s] = T*P_update[s]*np.transpose(T)+Q
u_smooth = np.zeros(S)
P_smooth = np.zeros(S)
u_smooth[S-1] = u_update[S-1]
P_smooth[S-1] = P_update[S-1]
for t in range(S-1,0,-1):
u_smooth[t-1] = u_update[t] + P_update[t]*np.transpose(T)/P_predict[t]*(u_smooth[t]-T*u_update[t])
P_smooth[t-1] = P_update[t] + P_update[t]*np.transpose(T)/P_predict[t]*(P_smooth[t]-P_predict[t])/P_predict[t]*T*P_update[t]
u_smooth = u_smooth[0:-1]
return u_smooth
T = 100
Y = np.random.normal(0,1,T)
param0 = np.array([1.3, 0.7, 0.8, 1])
param_star = minimize(Kalman_Filter, param0, method='BFGS', options={'xtol': 1e-8, 'disp': True})
Y_update = Kalman_Smoother(param_star.x, Y)
timevec = np.linspace(1,T,T)
plt.plot(timevec, Y_update,'r',timevec, Y,'b:')