00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <iostream>
00033 #include "fastlib/fastlib.h"
00034 #include "kalman_helper.h"
00035 #include "kalman.h"
00036
00037
00038 void KalmanFiltTimeInvariantMstUpdate(const ssm& lds, const Vector& y_t,
00039 const Vector& x_pred_t,
00040 const Matrix& p_pred_t,
00041 const Vector& y_pred_t,
00042 const Matrix& inno_cov_t,
00043 Vector& x_hat_t, Matrix& p_hat_t,
00044 Matrix& k_gain_t) {
00045
00046
00047
00048 int ny = lds.c_mat.n_rows();
00049 int nx = lds.a_mat.n_rows();
00050 Matrix c_trans; la::TransposeInit(lds.c_mat, &c_trans);
00051 Matrix tempm_0, tempm_1, tempm_2, tempm_3;
00052 Vector temp_1;
00053
00054
00055
00056
00057
00058 Matrix r_sqrt, r_sqrt_trans;
00059 Matrix p_pred_t_sqrt, p_pred_t_sqrt_trans;
00060 la::CholeskyInit(lds.r_mat, &r_sqrt_trans);
00061 la::TransposeInit(r_sqrt_trans, &r_sqrt);
00062 la::CholeskyInit(p_pred_t, &p_pred_t_sqrt_trans);
00063 la::TransposeInit(p_pred_t_sqrt_trans, &p_pred_t_sqrt);
00064
00065
00066
00067
00068
00069 Matrix pre_mat(ny + nx, ny + nx); pre_mat.SetZero();
00070 set_portion_of_matrix(r_sqrt_trans, 0, ny-1, 0, ny-1, &pre_mat);
00071 set_portion_of_matrix(p_pred_t_sqrt_trans, ny, ny + nx - 1, ny, ny + nx - 1,
00072 &pre_mat);
00073 la::MulInit(p_pred_t_sqrt_trans, c_trans, &tempm_0);
00074 set_portion_of_matrix(tempm_0, ny, ny + nx-1, 0, ny - 1, &pre_mat);
00075
00076
00077
00078
00079
00080 Matrix qq, rr; la::QRInit(pre_mat, &qq, &rr);
00081 Matrix post_mat; la::TransposeInit(rr, &post_mat);
00082
00083
00084
00085 extract_sub_matrix_init(post_mat, ny, ny + nx - 1, 0, ny-1, &tempm_1);
00086 extract_sub_matrix_init(post_mat, 0, ny-1, 0, ny-1, &tempm_2);
00087 la::InverseInit(tempm_2, &tempm_3);
00088 la::MulOverwrite(tempm_1,tempm_3, &k_gain_t);
00089 Matrix p_hat_t_sqrt;
00090 extract_sub_matrix_init(post_mat, ny, ny + nx - 1, ny, ny + nx - 1, &p_hat_t_sqrt);
00091 la::MulTransBOverwrite(p_hat_t_sqrt, p_hat_t_sqrt, &p_hat_t);
00092
00093
00094
00095
00096 la::ScaleInit(-1, y_pred_t, &temp_1);
00097 la::AddTo(y_t, &temp_1);
00098 la::MulOverwrite(k_gain_t, temp_1, &x_hat_t);
00099 la::AddTo(x_pred_t, &x_hat_t);
00100 };
00101
00102
00103 void KalmanFiltTimeInvariantTimeUpdate(const ssm& lds, const Vector& x_hat_t,
00104 const Matrix& p_hat_t,
00105 const Vector& y_t, const Vector& u_t,
00106 Vector& x_pred_t_next,
00107 Vector& y_pred_t_next,
00108 Matrix& p_pred_t_next,
00109 Matrix& inno_cov_t_next) {
00110
00111
00112
00113 Matrix tempm_1, tempm_2;
00114 Vector temp_1, temp_2;
00115 int nx = lds.a_mat.n_cols();
00116
00117
00118
00119
00120
00121 Matrix a_eff_mat(lds.a_mat.n_rows(), lds.a_mat.n_cols());
00122 Matrix q_eff_mat(lds.q_mat.n_rows(), lds.q_mat.n_cols());
00123 Matrix e_mat;
00124
00125
00126 schur(lds.a_mat, lds.s_mat, lds.r_mat, lds.c_mat, &a_eff_mat);
00127
00128
00129 Matrix inv_r_mat; la::InverseInit(lds.r_mat, &inv_r_mat);
00130 la::MulInit(lds.s_mat, inv_r_mat, &e_mat);
00131
00132
00133 Matrix s_trans;
00134 la::TransposeInit(lds.s_mat, &s_trans);
00135 schur(lds.q_mat, lds.s_mat, lds.r_mat, s_trans, &q_eff_mat);
00136
00137
00138 Matrix a_eff_trans;
00139 la::TransposeInit(a_eff_mat, &a_eff_trans);
00140
00141
00142
00143 Matrix pre_mat(nx + nx, nx);
00144 Matrix q_eff_sqrt_trans;
00145 Matrix p_hat_t_sqrt_trans;
00146 la::CholeskyInit(q_eff_mat, & q_eff_sqrt_trans);
00147 la::CholeskyInit(p_hat_t, &p_hat_t_sqrt_trans);
00148 la::MulInit(p_hat_t_sqrt_trans, a_eff_trans, &tempm_1);
00149 set_portion_of_matrix(tempm_1, 0, nx-1, 0, nx-1, &pre_mat);
00150 set_portion_of_matrix(q_eff_sqrt_trans, nx, 2*nx-1, 0, nx-1, &pre_mat);
00151
00152
00153 Matrix qq, rr;
00154 la::QRInit(pre_mat, &qq, &rr);
00155 Matrix post_mat;
00156 la::TransposeInit(rr, &post_mat);
00157
00158
00159 Matrix p_pred_t_next_sqrt;
00160 extract_sub_matrix_init(post_mat, 0, nx-1, 0, nx-1, &p_pred_t_next_sqrt);
00161 la::MulTransBOverwrite(p_pred_t_next_sqrt, p_pred_t_next_sqrt,
00162 &p_pred_t_next);
00163
00164 la::MulInit(lds.c_mat, p_pred_t_next_sqrt, &tempm_2);
00165 la::MulTransBOverwrite(tempm_2, tempm_2, &inno_cov_t_next);
00166 la::AddTo(lds.r_mat, &inno_cov_t_next);
00167
00168
00169
00170 la::MulInit(a_eff_mat, x_hat_t, &temp_1);
00171 la::MulInit(e_mat, y_t, &temp_2);
00172 la::AddTo(temp_1, &temp_2);
00173 la::MulOverwrite(lds.b_mat, u_t, &x_pred_t_next);
00174 la::AddTo(temp_2, &x_pred_t_next);
00175 la::MulOverwrite(lds.c_mat, x_pred_t_next, &y_pred_t_next);
00176 };