root/bdm/estim/libKF.cpp @ 357

Revision 357, 8.0 kB (checked in by mido, 15 years ago)

mnoho zmen:
1) presun FindXXX modulu do \system
2) zalozeni dokumentace \doc\local\library_structure.dox
3) presun obsahu \tests\UI primo do \tests
4) namisto \INSTALL zalozen \install.html, je to vhodnejsi pro uzivatele WINDOWS, a snad i obecne
5) snaha o predelani veskerych UI podle nove koncepce, soubory pmsm_ui.h, arx_ui.h, KF_ui.h, libDS_ui.h, libEF_ui.h a loggers_ui.h ponechavam
jen zdokumentacnich duvodu, nic by na nich jiz nemelo zaviset, a po zkontrolovani spravnosti provedenych uprav by mely byt smazany
6) predelani estimatoru tak, aby fungoval s novym UI konceptem
7) vytazeni tridy bdmroot do samostatneho souboru \bdm\bdmroot.h
8) pridana dokumentace pro zacleneni programu ASTYLE do Visual studia, ASTYLE pridan do instalacniho balicku pro Windows

  • Property svn:eol-style set to native
Line 
1
2#include "libKF.h"
3#include "..\user_info.h"
4
5namespace bdm{
6
7using std::endl;
8
9KalmanFull::KalmanFull ( mat A0, mat B0, mat C0, mat D0, mat Q0, mat R0, mat P0, vec mu0 ) {
10        dimx = A0.rows();
11        dimu = B0.cols();
12        dimy = C0.rows();
13
14        it_assert_debug ( A0.cols() ==dimx, "KalmanFull: A is not square" );
15        it_assert_debug ( B0.rows() ==dimx, "KalmanFull: B is not compatible" );
16        it_assert_debug ( C0.cols() ==dimx, "KalmanFull: C is not square" );
17        it_assert_debug ( ( D0.rows() ==dimy ) || ( D0.cols() ==dimu ), "KalmanFull: D is not compatible" );
18        it_assert_debug ( ( Q0.cols() ==dimx ) || ( Q0.rows() ==dimx ), "KalmanFull: Q is not compatible" );
19        it_assert_debug ( ( R0.cols() ==dimy ) || ( R0.rows() ==dimy ), "KalmanFull: R is not compatible" );
20
21        A = A0;
22        B = B0;
23        C = C0;
24        D = D0;
25        R = R0;
26        Q = Q0;
27        mu = mu0;
28        P = P0;
29       
30        ll = 0.0;
31        evalll=true;
32}
33
34void KalmanFull::bayes ( const vec &dt ) {
35        it_assert_debug ( dt.length() == ( dimy+dimu ),"KalmanFull::bayes wrong size of dt" );
36
37        vec u = dt.get ( dimy,dimy+dimu-1 );
38        vec y = dt.get ( 0,dimy-1 );
39        //Time update
40        mu = A*mu + B*u;
41        P  = A*P*A.transpose() + Q;
42
43        //Data update
44        _Ry = C*P*C.transpose() + R;
45        _iRy = inv ( _Ry );
46        _K = P*C.transpose() *_iRy;
47        P -= _K*C*P; // P = P -KCP;
48        mu += _K* ( y-C*mu-D*u );
49
50        if ( evalll ) {
51                //from enorm
52                vec x=y-C*mu-D*u;
53                ll = -0.5* ( R.cols() * 1.83787706640935 +log ( det ( _Ry ) ) +x* ( _iRy*x ) );
54        }
55};
56
57std::ostream &operator<< ( std::ostream &os, const KalmanFull &kf ) {
58        os << "mu:" << kf.mu << endl << "P:" << kf.P <<endl;
59        return os;
60}
61
62
63
64 /////////////////////////////// EKFS
65EKFfull::EKFfull ( ) : BM (),E() {};
66
67void EKFfull::set_parameters ( diffbifn* pfxu0,  diffbifn* phxu0,const mat Q0,const mat R0 ) {
68        pfxu = pfxu0;
69        phxu = phxu0;
70
71        dimx = pfxu0->_dimx();
72        dimy = phxu0->dimension();
73        dimu = pfxu0->_dimu();
74        E.epdf::set_parameters(dimx);
75       
76        A.set_size(dimx,dimx);
77        C.set_size(dimy,dimx);
78        //initialize matrices A C, later, these will be only updated!
79        pfxu->dfdx_cond ( mu,zeros ( dimu ),A,true );
80        B.clear();
81        phxu->dfdx_cond ( mu,zeros ( dimu ),C,true );
82        D.clear();
83
84        R = R0;
85        Q = Q0;
86}
87
88void EKFfull::bayes ( const vec &dt ) {
89        it_assert_debug ( dt.length() == ( dimy+dimu ),"KalmanFull::bayes wrong size of dt" );
90
91        vec u = dt.get ( dimy,dimy+dimu-1 );
92        vec y = dt.get ( 0,dimy-1 );
93       
94        pfxu->dfdx_cond ( mu,zeros ( dimu ),A,true );
95        phxu->dfdx_cond ( mu,zeros ( dimu ),C,true );
96
97        //Time update
98        mu = pfxu->eval(mu,u);// A*mu + B*u;
99        P  = A*P*A.transpose() + Q;
100
101        //Data update
102        _Ry = C*P*C.transpose() + R;
103        _iRy = inv ( _Ry );
104        _K = P*C.transpose() *_iRy;
105        P -= _K*C*P; // P = P -KCP;
106        vec yp = phxu->eval(mu,u);
107        mu += _K* ( y-yp );
108
109        E.set_mu(mu);
110
111        if ( BM::evalll ) {
112                //from enorm
113                vec x=y-yp;
114                BM::ll = -0.5* ( R.cols() * 1.83787706640935 +log ( det ( _Ry ) ) +x* ( _iRy*x ) );
115        }
116};
117
118
119
120void KalmanCh::set_parameters ( const mat &A0,const mat &B0,const mat &C0,const mat &D0,const chmat &Q0,const chmat &R0 ) {
121
122        ( ( Kalman<chmat>* ) this )->set_parameters ( A0,B0,C0,D0,Q0,R0 );
123        // Cholesky special!
124        preA=zeros(dimy+dimx+dimx,dimy+dimx);
125//      preA.clear();
126        preA.set_submatrix ( 0,0,R._Ch() );
127        preA.set_submatrix ( dimy+dimx,dimy,Q._Ch() );
128}
129
130
131void KalmanCh::bayes ( const vec &dt ) {
132
133        vec u = dt.get ( dimy,dimy+dimu-1 );
134        vec y = dt.get ( 0,dimy-1 );
135        vec pom(dimy);
136       
137        //TODO get rid of Q in qr()!
138//      mat Q;
139
140        //R and Q are already set in set_parameters()
141        preA.set_submatrix ( dimy,0, ( _P._Ch() ) *C.T() );
142        //Fixme can be more efficient if .T() is not used
143        preA.set_submatrix ( dimy,dimy, ( _P._Ch() ) *A.T() );
144
145//      if ( !qr ( preA,Q,postA ) ) it_warning ( "QR in kalman unstable!" );
146        if ( !qr ( preA,postA ) ) {it_warning ( "QR in kalman unstable!" );}
147
148        ( _Ry._Ch() ) =postA ( 0,dimy-1, 0,dimy-1 );
149        _K = inv(A)*( postA ( 0,dimy-1 ,dimy,dimy+dimx-1 ) ).T();
150        ( _P._Ch() ) = postA ( dimy,dimy+dimx-1,dimy,dimy+dimx-1 );
151       
152        _mu = A* ( _mu ) + B*u;
153        _yp = C*_mu -D*u;
154       
155        backward_substitution(_Ry._Ch(),( y-_yp),pom);
156        _mu +=  ( _K ) * pom;
157
158/*              cout << "P:" <<_P.to_mat() <<endl;
159                cout << "Ry:" <<_Ry.to_mat() <<endl;
160                cout << "_K:" <<_K <<endl;*/
161       
162        if ( evalll==true ) { //likelihood of observation y
163                ll=fy.evallog ( y );
164        }
165}
166
167
168
169void EKFCh::set_parameters ( diffbifn* pfxu0,  diffbifn* phxu0,const chmat Q0,const chmat R0 ) {
170        pfxu = pfxu0;
171        phxu = phxu0;
172
173        dimx = pfxu0->dimension();
174        dimy = phxu0->dimension();
175        dimu = pfxu0->_dimu();
176        // if mu is not set, set it to zeros, just for constant terms of A and C
177        if (_mu.length()!=dimx) _mu=zeros(dimx);
178        A=zeros(dimx,dimx);
179        C=zeros(dimy,dimx);
180        preA=zeros(dimy+dimx+dimx, dimy+dimx);
181       
182        //initialize matrices A C, later, these will be only updated!
183        pfxu->dfdx_cond ( _mu,zeros ( dimu ),A,true );
184//      pfxu->dfdu_cond ( *_mu,zeros ( dimu ),B,true );
185        B.clear();
186        phxu->dfdx_cond ( _mu,zeros ( dimu ),C,true );
187//      phxu->dfdu_cond ( *_mu,zeros ( dimu ),D,true );
188        D.clear();
189
190        R = R0;
191        Q = Q0;
192
193        // Cholesky special!
194        preA.clear();
195        preA.set_submatrix ( 0,0,R._Ch() );
196        preA.set_submatrix ( dimy+dimx,dimy,Q._Ch() );
197}
198
199
200void EKFCh::bayes ( const vec &dt ) {
201
202        vec pom(dimy);
203        vec u = dt.get ( dimy,dimy+dimu-1 );
204        vec y = dt.get ( 0,dimy-1 );
205
206        pfxu->dfdx_cond ( _mu,u,A,false ); //update A by a derivative of fx
207        phxu->dfdx_cond ( _mu,u,C,false ); //update A by a derivative of fx
208
209        //R and Q are already set in set_parameters()
210        preA.set_submatrix ( dimy,0, ( _P._Ch() ) *C.T() );
211        //Fixme can be more efficient if .T() is not used
212        preA.set_submatrix ( dimy,dimy, ( _P._Ch() ) *A.T() );
213
214//      mat Sttm = _P->to_mat();
215//      cout << preA <<endl;
216//      cout << "_mu:" << _mu <<endl;
217
218//      if ( !qr ( preA,Q,postA ) ) it_warning ( "QR in kalman unstable!" );
219        if ( !qr ( preA,postA ) ) {it_warning ( "QR in kalman unstable!" );}
220
221
222        ( _Ry._Ch() ) =postA ( 0,dimy-1, 0,dimy-1 );
223        _K = inv(A)*( postA ( 0,dimy-1 ,dimy,dimy+dimx-1 ) ).T();
224        ( _P._Ch() ) = postA ( dimy,dimy+dimx-1,dimy,dimy+dimx-1 );
225       
226//      mat iRY = inv(_Ry->to_mat());
227//      mat Stt = Sttm - Sttm * C.T() * iRY * C * Sttm;
228//      mat _K2 = Stt*C.T()*inv(R.to_mat());
229
230        // prediction
231        _mu = pfxu->eval ( _mu ,u );
232        _yp = phxu->eval ( _mu,u );
233       
234/*      vec mu2 = *_mu + ( _K2 ) * ( y-*_yp );*/
235       
236        //correction //= initial value is already prediction!
237        backward_substitution(_Ry._Ch(),( y-_yp ),pom);
238        _mu += ( _K ) *pom ;
239
240/*      _K = (_P->to_mat())*C.transpose() * ( _iRy->to_mat() );
241        *_mu = pfxu->eval ( *_mu ,u ) + ( _K )* ( y-*_yp );*/
242       
243//              cout << "P:" <<_P.to_mat() <<endl;
244//              cout << "Ry:" <<_Ry.to_mat() <<endl;
245//      cout << "_mu:" <<_mu <<endl;
246//      cout << "dt:" <<dt <<endl;
247
248        if ( evalll==true ) { //likelihood of observation y
249                ll=fy.evallog ( y );
250        }
251}
252
253void EKFCh::from_setting( const Setting &root ) 
254{       
255        diffbifn* IM = UI::build<diffbifn>(root, "IM");
256        diffbifn* OM = UI::build<diffbifn>(root, "OM");
257       
258        //statistics
259        int dim=IM->dimension();
260        vec mu0;
261        if(root.exists("mu0"))
262                UI::get( mu0, root, "mu0");
263        else
264                mu0=zeros(dim);
265
266        mat P0;
267        if(root.exists("dP0"))
268        {
269                vec dP0;
270                UI::get( dP0, root, "dP0");
271                P0=diag(dP0);
272        }
273        else if ( root.exists( "P0" ) )
274                UI::get(P0, root, "P0");
275        else
276                P0=eye(dim);
277       
278        set_statistics(mu0,P0);
279       
280        //parameters
281        vec dQ, dR;
282        UI::get( dQ, root, "dQ");
283        UI::get( dR, root, "dR");
284        set_parameters(IM, OM, diag(dQ), diag(dR));
285
286        //connect
287        RV* drv = UI::build<RV>(root, "drv");
288        set_drv(*drv);
289        RV* rv = UI::build<RV>(root, "rv");
290        set_rv(*rv);
291       
292        string options;
293        if(root.lookupValue( "options", options ))
294                set_options(options);   
295}
296
297/*void EKFCh::to_setting( Setting &root ) const
298{       
299        Transport::to_setting( root );
300
301        Setting &kilometers_setting = root.add("kilometers", Setting::TypeInt );
302        kilometers_setting = kilometers;
303
304        UI::save( passengers, root, "passengers" );
305}*/
306
307void MultiModel::from_setting( const Setting &root ) 
308{       
309        Array<EKFCh*> A;
310        UI::get( A, root, "models");
311       
312        set_parameters(A);
313        set_drv(A(0)->_drv());
314        //set_rv(A(0)->_rv());
315
316        string options;
317        if(root.lookupValue( "options", options ))
318                set_options(options);   
319}
320
321/*void MultiModel::to_setting( Setting &root ) const
322{       
323        Transport::to_setting( root );
324
325        Setting &kilometers_setting = root.add("kilometers", Setting::TypeInt );
326        kilometers_setting = kilometers;
327
328        UI::save( passengers, root, "passengers" );
329}*/
330
331
332}
Note: See TracBrowser for help on using the browser.