root/bdm/stat/libEF.cpp @ 357

Revision 357, 7.5 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#include <math.h>
2
3#include <itpp/base/bessel.h>
4#include "libEF.h"
5#include "..\user_info.h"
6
7namespace bdm{
8
9Uniform_RNG UniRNG;
10Normal_RNG NorRNG;
11Gamma_RNG GamRNG;
12
13using std::cout;
14
15void BMEF::bayes ( const vec &dt ) {this->bayes ( dt,1.0 );};
16
17vec egiw::sample() const {
18        it_warning ( "Function not implemented" );
19        return vec_1 ( 0.0 );
20}
21
22double egiw::evallog_nn ( const vec &val ) const {
23        int vend = val.length()-1;
24
25        if ( dimx==1 ) { //same as the following, just quicker.
26                double r = val ( vend ); //last entry!
27                vec Psi ( nPsi+dimx );
28                Psi ( 0 ) = -1.0;
29                Psi.set_subvector ( 1,val ( 0,vend-1 ) ); // fill the rest
30
31                double Vq=V.qform ( Psi );
32                return -0.5* ( nu*log ( r ) + Vq /r );
33        }
34        else {
35                mat Th= reshape ( val ( 0,nPsi*dimx-1 ),nPsi,dimx );
36                fsqmat R ( reshape ( val ( nPsi*dimx,vend ),dimx,dimx ) );
37                mat Tmp=concat_vertical ( -eye ( dimx ),Th );
38                fsqmat iR ( dimx );
39                R.inv ( iR );
40
41                return -0.5* ( nu*R.logdet() + trace ( iR.to_mat() *Tmp.T() *V.to_mat() *Tmp ) );
42        }
43}
44
45double egiw::lognc() const {
46        const vec& D = V._D();
47
48        double m = nu - nPsi -dimx-1;
49#define log2  0.693147180559945286226763983
50#define logpi 1.144729885849400163877476189
51#define log2pi 1.83787706640935
52#define Inf std::numeric_limits<double>::infinity()
53
54        double nkG = 0.5* dimx* ( -nPsi *log2pi + sum ( log ( D ( dimx,D.length()-1 ) ) ) );
55        // temporary for lgamma in Wishart
56        double lg=0;
57        for ( int i =0; i<dimx;i++ ) {lg+=lgamma ( 0.5* ( m-i ) );}
58
59        double nkW = 0.5* ( m*sum ( log ( D ( 0,dimx-1 ) ) ) ) \
60                     - 0.5*dimx* ( m*log2 + 0.5* ( dimx-1 ) *log2pi )  - lg;
61
62        it_assert_debug ( ( ( -nkG-nkW ) >-Inf ) && ( ( -nkG-nkW ) <Inf ), "ARX improper" );
63        return -nkG-nkW;
64}
65
66vec egiw::est_theta() const {
67        if ( dimx==1 ) {
68                const mat &L = V._L();
69                int end = L.rows() - 1;
70
71                mat iLsub = ltuinv ( L ( dimx,end,dimx,end ) );
72
73                vec L0 = L.get_col(0);
74
75                return iLsub * L0(1,end);
76        }
77        else {
78                it_error("ERROR: est_theta() not implemented for dimx>1");
79                return 0;
80        }
81}
82
83ldmat egiw::est_theta_cov() const {
84        if ( dimx == 1 ) {
85                const mat &L = V._L();
86                const vec &D = V._D();
87                int end = D.length() - 1;
88
89                mat Lsub = L ( 1, end, 1, end);
90                mat Dsub = diag(D(1, end));
91
92                return inv( transpose(Lsub) * Dsub * Lsub );
93
94        }
95        else {
96                it_error("ERROR: est_theta_cov() not implemented for dimx>1");
97                return 0;
98        }
99
100}
101
102vec egiw::mean() const {
103
104        if ( dimx==1 ) {
105                const vec &D= V._D();
106                int end = D.length()-1;
107
108                vec m ( dim );
109                m.set_subvector ( 0, est_theta() );
110                m ( end ) = D ( 0 ) / ( nu -nPsi -2*dimx -2 );
111                return m;
112        }
113        else {
114                mat M;
115                mat R;
116                mean_mat ( M,R );
117                return cvectorize ( concat_vertical ( M,R ) );
118        }
119
120}
121
122vec egiw::variance() const {
123
124        if ( dimx==1 ) {
125                int l=V.rows();
126                const ldmat tmp(V,linspace(1,l-1));
127                ldmat itmp(l);
128                tmp.inv(itmp);
129                double cove = V._D() ( 0 ) / ( nu -nPsi -2*dimx -2 );
130               
131                vec var(l);
132                var.set_subvector(0,diag(itmp.to_mat())*cove);
133                var(l-1)=cove*cove/( nu -nPsi -2*dimx -2 );
134                return var;
135        }
136        else {it_error("not implemented"); return vec(0);}
137}
138
139void egiw::mean_mat ( mat &M, mat&R ) const {
140        const mat &L= V._L();
141        const vec &D= V._D();
142        int end = L.rows()-1;
143
144        ldmat ldR ( L ( 0,dimx-1,0,dimx-1 ), D ( 0,dimx-1 ) / ( nu -nPsi -2*dimx -2 ) ); //exp val of R
145        mat iLsub=ltuinv ( L ( dimx,end,dimx,end ) );
146
147        // set mean value
148        mat Lpsi = L ( dimx,end,0,dimx-1 );
149        M= iLsub*Lpsi;
150        R= ldR.to_mat()  ;
151}
152
153vec egamma::sample() const {
154        vec smp ( dim);
155        int i;
156
157        for ( i=0; i<dim; i++ ) {
158                if ( beta ( i ) >std::numeric_limits<double>::epsilon() ) {
159                        GamRNG.setup ( alpha ( i ),beta ( i ) );
160                }
161                else {
162                        GamRNG.setup ( alpha ( i ),std::numeric_limits<double>::epsilon() );
163                }
164#pragma omp critical
165                smp ( i ) = GamRNG();
166        }
167
168        return smp;
169}
170
171// mat egamma::sample ( int N ) const {
172//      mat Smp ( rv.count(),N );
173//      int i,j;
174//
175//      for ( i=0; i<rv.count(); i++ ) {
176//              GamRNG.setup ( alpha ( i ),beta ( i ) );
177//
178//              for ( j=0; j<N; j++ ) {
179//                      Smp ( i,j ) = GamRNG();
180//              }
181//      }
182//
183//      return Smp;
184// }
185
186double egamma::evallog ( const vec &val ) const {
187        double res = 0.0; //the rest will be added
188        int i;
189
190        for ( i=0; i<dim; i++ ) {
191                res += ( alpha ( i ) - 1 ) *std::log ( val ( i ) ) - beta ( i ) *val ( i );
192        }
193        double tmp=res-lognc();;
194        it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
195        return tmp;
196}
197
198double egamma::lognc() const {
199        double res = 0.0; //will be added
200        int i;
201
202        for ( i=0; i<dim; i++ ) {
203                res += lgamma ( alpha ( i ) ) - alpha ( i ) *std::log ( beta ( i ) ) ;
204        }
205
206        return res;
207}
208
209//MGamma
210void mgamma::set_parameters ( double k0, const vec &beta0 ) {
211        k=k0;
212        ep = &epdf;
213        epdf.set_parameters ( k*ones ( beta0.length()),beta0 );
214        dimc = ep->dimension();
215};
216
217ivec eEmp::resample (RESAMPLING_METHOD method) {
218        ivec ind=zeros_i ( n );
219        ivec N_babies = zeros_i ( n );
220        vec cumDist = cumsum ( w );
221        vec u ( n );
222        int i,j,parent;
223        double u0;
224
225        switch ( method ) {
226                case MULTINOMIAL:
227                        u ( n - 1 ) = pow ( UniRNG.sample(), 1.0 / n );
228
229                        for ( i = n - 2;i >= 0;i-- ) {
230                                u ( i ) = u ( i + 1 ) * pow ( UniRNG.sample(), 1.0 / ( i + 1 ) );
231                        }
232
233                        break;
234
235                case STRATIFIED:
236
237                        for ( i = 0;i < n;i++ ) {
238                                u ( i ) = ( i + UniRNG.sample() ) / n;
239                        }
240
241                        break;
242
243                case SYSTEMATIC:
244                        u0 = UniRNG.sample();
245
246                        for ( i = 0;i < n;i++ ) {
247                                u ( i ) = ( i + u0 ) / n;
248                        }
249
250                        break;
251
252                default:
253                        it_error ( "PF::resample(): Unknown resampling method" );
254        }
255
256        // U is now full
257        j = 0;
258
259        for ( i = 0;i < n;i++ ) {
260                while ( u ( i ) > cumDist ( j ) ) j++;
261
262                N_babies ( j ) ++;
263        }
264        // We have assigned new babies for each Particle
265        // Now, we fill the resulting index such that:
266        // * particles with at least one baby should not move *
267        // This assures that reassignment can be done inplace;
268
269        // find the first parent;
270        parent=0; while ( N_babies ( parent ) ==0 ) parent++;
271
272        // Build index
273        for ( i = 0;i < n;i++ ) {
274                if ( N_babies ( i ) > 0 ) {
275                        ind ( i ) = i;
276                        N_babies ( i ) --; //this index was now replicated;
277                }
278                else {
279                        // test if the parent has been fully replicated
280                        // if yes, find the next one
281                        while ( ( N_babies ( parent ) ==0 ) || ( N_babies ( parent ) ==1 && parent>i ) ) parent++;
282
283                        // Replicate parent
284                        ind ( i ) = parent;
285
286                        N_babies ( parent ) --; //this index was now replicated;
287                }
288
289        }
290
291        // copy the internals according to ind
292        for ( i=0;i<n;i++ ) {
293                if ( ind ( i ) !=i ) {
294                        samples ( i ) =samples ( ind ( i ) );
295                }
296                w ( i ) = 1.0/n;
297        }
298
299        return ind;
300}
301
302void eEmp::set_statistics ( const vec &w0, const epdf* epdf0 ) {
303        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0");
304        dim = epdf0->dimension();
305        w=w0;
306        w/=sum ( w0 );//renormalize
307        n=w.length();
308        samples.set_size ( n );
309        dim = epdf0->dimension();
310
311        for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();}
312}
313
314void eEmp::set_samples ( const epdf* epdf0 ) {
315        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0");
316        w=1;
317        w/=sum ( w );//renormalize
318
319        for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();}
320}
321
322void migamma_ref::from_setting( const Setting &root ) 
323{                               
324        vec ref;
325        UI::get( ref, root, "ref" );
326        set_parameters(root["k"],ref,root["l"]);
327}
328
329/*void migamma_ref::to_setting( Setting &root ) const
330{       
331        Transport::to_setting( root );
332
333        Setting &kilometers_setting = root.add("kilometers", Setting::TypeInt );
334        kilometers_setting = kilometers;
335
336        UI::save( passengers, root, "passengers" );
337}*/
338
339
340void mlognorm::from_setting( const Setting &root ) 
341{       
342        vec mu0;
343        UI::get( mu0, root, "mu0");
344        set_parameters(mu0.length(),root["k"]);
345        condition(mu0);
346}
347
348/*void mlognorm::to_setting( Setting &root ) const
349{       
350        Transport::to_setting( root );
351
352        Setting &kilometers_setting = root.add("kilometers", Setting::TypeInt );
353        kilometers_setting = kilometers;
354
355        UI::save( passengers, root, "passengers" );
356}*/
357
358
359};
Note: See TracBrowser for help on using the browser.