00001
00002
00003
00004
00005 #include "LinearModel.hpp"
00006
00007 using namespace indii::ml::filter;
00008
00009 namespace aux = indii::ml::aux;
00010
00011
00012
00013
00014
00015
00016 LinearModel::LinearModel(aux::matrix& A, aux::matrix& G,
00017 aux::symmetric_matrix& Q, aux::matrix& C, aux::symmetric_matrix& R) :
00018 N(A.size1()), M(C.size1()), A(A), AT(trans(A)), G(G), GT(trans(G)), Q(Q),
00019 C(C), CT(trans(C)), R(R), AI(N,N) {
00020
00021 #ifndef NDEBUG
00022 assert(A.size1() == N);
00023 assert(A.size2() == N);
00024 assert(G.size1() == N);
00025 assert(G.size2() == N);
00026 assert(Q.size1() == N);
00027 assert(Q.size2() == N);
00028 assert(C.size1() == M);
00029 assert(C.size2() == N);
00030 assert(R.size1() == M);
00031 assert(R.size2() == M);
00032 #endif
00033
00034
00035 aux::matrix tmp(A);
00036 aux::inv(tmp,AI);
00037 }
00038
00039 LinearModel::~LinearModel() {
00040
00041 }
00042
00043 aux::GaussianPdf LinearModel::p_xtnp1_ytn(const aux::GaussianPdf& p_xtn_ytn,
00044 const unsigned int delta) {
00045 const aux::vector& x_xtn_ytn = p_xtn_ytn.getExpectation();
00046 const aux::symmetric_matrix& P_xtn_ytn = p_xtn_ytn.getCovariance();
00047 aux::vector x_xtnp1_ytn(N);
00048 aux::symmetric_matrix P_xtnp1_ytn(N,N);
00049
00050 noalias(x_xtnp1_ytn) = prod(A,x_xtn_ytn);
00051 aux::matrix X(N,N);
00052 noalias(X) = prod(P_xtn_ytn,AT);
00053 noalias(P_xtnp1_ytn) = prod(A,X);
00054 noalias(X) = prod(Q,GT);
00055 noalias(P_xtnp1_ytn) += prod(G,X);
00056
00057 return aux::GaussianPdf(x_xtnp1_ytn, P_xtnp1_ytn);
00058 }
00059
00060
00061
00062
00063
00064
00065 aux::GaussianPdf LinearModel::p_xtnp1_ytnp1(
00066 const aux::GaussianPdf& p_xtnp1_ytn, const aux::vector& ytnp1,
00067 const unsigned int delta) {
00068 const aux::vector& x_xtnp1_ytn = p_xtnp1_ytn.getExpectation();
00069 const aux::symmetric_matrix& P_xtnp1_ytn = p_xtnp1_ytn.getCovariance();
00070 aux::vector x_xtnp1_ytnp1(N);
00071 aux::symmetric_matrix P_xtnp1_ytnp1(N);
00072 aux::matrix X(M,M), Y(M,M), Z(N,M), K_tnp1(N,M);
00073
00074 noalias(Z) = prod(P_xtnp1_ytn, CT);
00075 noalias(X) = prod(C, Z) + R;
00076 aux::inv(X, Y);
00077
00078 noalias(Z) = prod(P_xtnp1_ytn, CT);
00079 noalias(K_tnp1) = prod(Z, Y);
00080
00081 noalias(x_xtnp1_ytnp1) = x_xtnp1_ytn
00082 + prod(K_tnp1,aux::vector(ytnp1 - prod(C,x_xtnp1_ytn)));
00083 noalias(P_xtnp1_ytnp1) = P_xtnp1_ytn
00084 - prod(K_tnp1,aux::matrix(prod(C,P_xtnp1_ytn)));
00085
00086 return aux::GaussianPdf(x_xtnp1_ytnp1, P_xtnp1_ytnp1);
00087 }
00088
00089 aux::GaussianPdf LinearModel::p_y_x(const aux::GaussianPdf& p_x) {
00090 const aux::vector& x = p_x.getExpectation();
00091 const aux::symmetric_matrix& P_x = p_x.getCovariance();
00092 aux::vector y(M);
00093 aux::symmetric_matrix P_y(M,M);
00094 aux::matrix X(M,M);
00095
00096 noalias(y) = prod(C,x);
00097
00098 noalias(X) = prod(P_x, CT);
00099 noalias(P_y) = prod(C, X) + R;
00100
00101 return aux::GaussianPdf(y, P_y);
00102 }
00103
00104 aux::GaussianPdf LinearModel::p_xtn_ytT(const aux::GaussianPdf& p_xtnp1_ytT,
00105 const aux::GaussianPdf& p_xtnp1_ytn, const aux::GaussianPdf& p_xtn_ytn,
00106 const unsigned int delta) {
00107 const aux::vector& x_xtnp1_ytT = p_xtnp1_ytT.getExpectation();
00108 const aux::symmetric_matrix& P_xtnp1_ytT = p_xtnp1_ytT.getCovariance();
00109 const aux::vector& x_xtnp1_ytn = p_xtnp1_ytn.getExpectation();
00110 const aux::symmetric_matrix& P_xtnp1_ytn = p_xtnp1_ytn.getCovariance();
00111 const aux::vector& x_xtn_ytn = p_xtn_ytn.getExpectation();
00112 const aux::symmetric_matrix& P_xtn_ytn = p_xtn_ytn.getCovariance();
00113 aux::vector x_xtn_ytT(N);
00114 aux::symmetric_matrix P_xtn_ytT(N);
00115
00116 aux::matrix L_tn(N,N), LT_tn(N,N), PI_xtnp1_ytn(N,N), X(N,N);
00117 noalias(X) = P_xtnp1_ytn;
00118 aux::inv(X, PI_xtnp1_ytn);
00119
00120 noalias(X) = prod(AT, PI_xtnp1_ytn);
00121 noalias(L_tn) = prod(P_xtn_ytn, X);
00122 noalias(LT_tn) = trans(L_tn);
00123
00124 noalias(x_xtn_ytT) = x_xtn_ytn + prod(L_tn, x_xtnp1_ytT - x_xtnp1_ytn);
00125 noalias(X) = prod(P_xtnp1_ytT - P_xtnp1_ytn, LT_tn);
00126 noalias(P_xtn_ytT) = P_xtn_ytn + prod(L_tn, X);
00127
00128 return aux::GaussianPdf(x_xtn_ytT, P_xtn_ytT);
00129 }
00130
00131 aux::GaussianPdf LinearModel::p_xtnm1_ytn(const aux::GaussianPdf& p_xtn_ytn,
00132 const unsigned int delta) {
00133
00134 const aux::vector x_xtn_ytn = p_xtn_ytn.getExpectation();
00135 const aux::matrix P_xtn_ytn = p_xtn_ytn.getCovariance();
00136
00137 aux::matrix A_b(N,N);
00138 aux::matrix G_b(N,N);
00139 aux::matrix Q_b(N,N);
00140 aux::vector w_b(N);
00141
00142 aux::matrix PI_xtn_ytn(N,N);
00143 aux::identity_matrix I(N);
00144 aux::matrix X(N,N);
00145
00146 noalias(X) = P_xtn_ytn;
00147 aux::inv(X, PI_xtn_ytn);
00148
00149 noalias(A_b) = prod(AI,G);
00150 A_b = prod(A_b,Q);
00151 A_b = prod(A_b,GT);
00152 A_b = prod(A_b,PI_xtn_ytn);
00153 A_b = I - A_b;
00154 A_b = prod(AI, A_b);
00155
00156 noalias(G_b) = -1.0 * prod(AI,G);
00157
00158 noalias(Q_b) = prod(Q,GT);
00159 Q_b = prod(Q_b,PI_xtn_ytn);
00160 Q_b = prod(Q_b,G);
00161 Q_b = prod(Q_b,Q);
00162 Q_b = Q - Q_b;
00163
00164 noalias(w_b) = prod(PI_xtn_ytn,x_xtn_ytn);
00165 w_b = prod(GT,w_b);
00166 w_b = prod(Q,w_b);
00167 w_b *= -1.0;
00168
00169
00170 aux::vector x_xtnm1_ytn(N);
00171 aux::symmetric_matrix P_xtnm1_ytn(N,N);
00172
00173 noalias(x_xtnm1_ytn) = prod(A_b,x_xtn_ytn) + prod(G_b,w_b);
00174 noalias(X) = prod(A_b,P_xtn_ytn);
00175 noalias(P_xtnm1_ytn) = prod(X,trans(A_b));
00176 noalias(X) = prod(G_b,Q_b);
00177 noalias(P_xtnm1_ytn) += prod(X,trans(G_b));
00178
00179 return aux::GaussianPdf(x_xtnm1_ytn, P_xtnm1_ytn);
00180 }
00181
00182 aux::GaussianPdf LinearModel::p_xtnm1_ytnm1(
00183 const aux::GaussianPdf& p_xtnm1_ytn, const aux::vector& ytnm1,
00184 const unsigned int delta) {
00185 return p_xtnp1_ytnp1(p_xtnm1_ytn, ytnm1, delta);
00186 }