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

Revision 404, 7.6 kB (checked in by smidl, 15 years ago)

Change in epdf: evallog returns -inf for points out of support. Merger is aware of it now.

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