root/bdm/stat/libEF.cpp @ 214

Revision 214, 5.8 kB (checked in by smidl, 15 years ago)

debug asserts for infinite likelihoods

Line 
1#include <itpp/itbase.h>
2#include <itpp/base/bessel.h>
3#include "libEF.h"
4#include <math.h>
5
6using namespace itpp;
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 ( xdim==1 ) { //same as the following, just quicker.
25                double r = val ( vend ); //last entry!
26                vec Psi ( nPsi+xdim );
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*xdim-1 ),nPsi,xdim );
35                fsqmat R ( reshape ( val ( nPsi*xdim,vend ),xdim,xdim ) );
36                mat Tmp=concat_vertical ( -eye ( xdim ),Th );
37                fsqmat iR ( xdim );
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 -xdim-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* xdim* ( -nPsi *log2pi + sum ( log ( D ( xdim,D.length()-1 ) ) ) );
54        // temporary for lgamma in Wishart
55        double lg=0;
56        for ( int i =0; i<xdim;i++ ) {lg+=lgamma ( 0.5* ( m-i ) );}
57
58        double nkW = 0.5* ( m*sum ( log ( D ( 0,xdim-1 ) ) ) ) \
59                     - 0.5*xdim* ( m*log2 + 0.5* ( xdim-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 ( xdim==1 ) {
68                const mat &L= V._L();
69                const vec &D= V._D();
70                int end = L.rows()-1;
71
72                vec m ( rv.count() );
73                mat iLsub = ltuinv ( L ( xdim,end,xdim,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*xdim -2 );
79                return m;
80        } else {
81                mat M;
82                mat R;
83                mean_mat(M,R);
84                return cvectorize (concat_vertical(M,R));
85        }
86
87}
88void egiw::mean_mat(mat &M, mat&R) const {
89        const mat &L= V._L();
90        const vec &D= V._D();
91        int end = L.rows()-1;
92               
93        ldmat ldR ( L ( 0,xdim-1,0,xdim-1 ), D ( 0,xdim-1 ) / ( nu -nPsi -2*xdim -2 ) ); //exp val of R
94        mat iLsub=ltuinv ( L ( xdim,end,xdim,end ) );
95       
96        // set mean value
97        mat Lpsi = L ( xdim,end,0,xdim-1 );
98        M= iLsub*Lpsi;
99        R= ldR.to_mat()  ;
100}
101
102vec egamma::sample() const {
103        vec smp ( rv.count() );
104        int i;
105
106        for ( i=0; i<rv.count(); i++ ) {
107                GamRNG.setup ( alpha ( i ),beta ( i ) );
108#pragma omp critical
109                smp ( i ) = GamRNG();
110        }
111
112        return smp;
113}
114
115// mat egamma::sample ( int N ) const {
116//      mat Smp ( rv.count(),N );
117//      int i,j;
118//
119//      for ( i=0; i<rv.count(); i++ ) {
120//              GamRNG.setup ( alpha ( i ),beta ( i ) );
121//
122//              for ( j=0; j<N; j++ ) {
123//                      Smp ( i,j ) = GamRNG();
124//              }
125//      }
126//
127//      return Smp;
128// }
129
130double egamma::evallog ( const vec &val ) const {
131        double res = 0.0; //the rest will be added
132        int i;
133
134        for ( i=0; i<rv.count(); i++ ) {
135                res += ( alpha ( i ) - 1 ) *std::log ( val ( i ) ) - beta ( i ) *val ( i );
136        }
137        double tmp=res-lognc();;
138        it_assert_debug(std::isfinite(tmp),"Infinite value");
139        return tmp;
140}
141
142double egamma::lognc() const {
143        double res = 0.0; //will be added
144        int i;
145
146        for ( i=0; i<rv.count(); i++ ) {
147                res += lgamma ( alpha ( i ) ) - alpha ( i ) *std::log ( beta ( i ) ) ;
148        }
149
150        return res;
151}
152
153//MGamma
154mgamma::mgamma ( const RV &rv,const RV &rvc ) : mEF ( rv,rvc ), epdf ( rv ) {vec* tmp; epdf._param ( tmp,_beta );};
155
156void mgamma::set_parameters ( double k0 ) {
157        k=k0;
158        ep = &epdf;
159        epdf.set_parameters ( k*ones ( rv.count() ),*_beta );
160};
161
162ivec eEmp::resample ( RESAMPLING_METHOD method ) {
163        ivec ind=zeros_i ( n );
164        ivec N_babies = zeros_i ( n );
165        vec cumDist = cumsum ( w );
166        vec u ( n );
167        int i,j,parent;
168        double u0;
169
170        switch ( method ) {
171                case MULTINOMIAL:
172                        u ( n - 1 ) = pow ( UniRNG.sample(), 1.0 / n );
173
174                        for ( i = n - 2;i >= 0;i-- ) {
175                                u ( i ) = u ( i + 1 ) * pow ( UniRNG.sample(), 1.0 / ( i + 1 ) );
176                        }
177
178                        break;
179
180                case STRATIFIED:
181
182                        for ( i = 0;i < n;i++ ) {
183                                u ( i ) = ( i + UniRNG.sample() ) / n;
184                        }
185
186                        break;
187
188                case SYSTEMATIC:
189                        u0 = UniRNG.sample();
190
191                        for ( i = 0;i < n;i++ ) {
192                                u ( i ) = ( i + u0 ) / n;
193                        }
194
195                        break;
196
197                default:
198                        it_error ( "PF::resample(): Unknown resampling method" );
199        }
200
201        // U is now full
202        j = 0;
203
204        for ( i = 0;i < n;i++ ) {
205                while ( u ( i ) > cumDist ( j ) ) j++;
206
207                N_babies ( j ) ++;
208        }
209        // We have assigned new babies for each Particle
210        // Now, we fill the resulting index such that:
211        // * particles with at least one baby should not move *
212        // This assures that reassignment can be done inplace;
213
214        // find the first parent;
215        parent=0; while ( N_babies ( parent ) ==0 ) parent++;
216
217        // Build index
218        for ( i = 0;i < n;i++ ) {
219                if ( N_babies ( i ) > 0 ) {
220                        ind ( i ) = i;
221                        N_babies ( i ) --; //this index was now replicated;
222                }
223                else {
224                        // test if the parent has been fully replicated
225                        // if yes, find the next one
226                        while ( ( N_babies ( parent ) ==0 ) || ( N_babies ( parent ) ==1 && parent>i ) ) parent++;
227
228                        // Replicate parent
229                        ind ( i ) = parent;
230
231                        N_babies ( parent ) --; //this index was now replicated;
232                }
233
234        }
235
236        // copy the internals according to ind
237        for ( i=0;i<n;i++ ) {
238                if ( ind ( i ) !=i ) {
239                        samples ( i ) =samples ( ind ( i ) );
240                }
241                w ( i ) = 1.0/n;
242        }
243
244        return ind;
245}
246
247void eEmp::set_parameters ( const vec &w0, const epdf* epdf0 ) {
248        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0");
249        w=w0;
250        w/=sum ( w0 );//renormalize
251        n=w.length();
252        samples.set_size ( n );
253
254        for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();}
255}
256
257void eEmp::set_samples (  const epdf* epdf0 ) {
258        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0");
259        w=1;
260        w/=sum ( w );//renormalize
261
262        for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();}
263}
Note: See TracBrowser for help on using the browser.