root/bdm/stat/libEF.cpp @ 281

Revision 281, 6.2 kB (checked in by smidl, 15 years ago)

new version of mpf_test for TR2245

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