root/library/bdm/stat/exp_family.cpp @ 487

Revision 487, 7.5 kB (checked in by smidl, 15 years ago)

1st step of mpdf redesign - BROKEN compile

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