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

Revision 461, 7.6 kB (checked in by vbarta, 15 years ago)

mpdf (& its dependencies) reformat: now using shared_ptr, moved virtual method bodies to .cpp

  • 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
213void mgamma::set_parameters(double k0, const vec &beta0) {
214        k = k0;
215        iepdf->set_parameters(k * ones(beta0.length()), beta0);
216        dimc = e()->dimension();
217}
218
219ivec eEmp::resample (RESAMPLING_METHOD method) {
220        ivec ind=zeros_i ( n );
221        ivec N_babies = zeros_i ( n );
222        vec cumDist = cumsum ( w );
223        vec u ( n );
224        int i,j,parent;
225        double u0;
226
227        switch ( method ) {
228                case MULTINOMIAL:
229                        u ( n - 1 ) = pow ( UniRNG.sample(), 1.0 / n );
230
231                        for ( i = n - 2;i >= 0;i-- ) {
232                                u ( i ) = u ( i + 1 ) * pow ( UniRNG.sample(), 1.0 / ( i + 1 ) );
233                        }
234
235                        break;
236
237                case STRATIFIED:
238
239                        for ( i = 0;i < n;i++ ) {
240                                u ( i ) = ( i + UniRNG.sample() ) / n;
241                        }
242
243                        break;
244
245                case SYSTEMATIC:
246                        u0 = UniRNG.sample();
247
248                        for ( i = 0;i < n;i++ ) {
249                                u ( i ) = ( i + u0 ) / n;
250                        }
251
252                        break;
253
254                default:
255                        it_error ( "PF::resample(): Unknown resampling method" );
256        }
257
258        // U is now full
259        j = 0;
260
261        for ( i = 0;i < n;i++ ) {
262                while ( u ( i ) > cumDist ( j ) ) j++;
263
264                N_babies ( j ) ++;
265        }
266        // We have assigned new babies for each Particle
267        // Now, we fill the resulting index such that:
268        // * particles with at least one baby should not move *
269        // This assures that reassignment can be done inplace;
270
271        // find the first parent;
272        parent=0; while ( N_babies ( parent ) ==0 ) parent++;
273
274        // Build index
275        for ( i = 0;i < n;i++ ) {
276                if ( N_babies ( i ) > 0 ) {
277                        ind ( i ) = i;
278                        N_babies ( i ) --; //this index was now replicated;
279                }
280                else {
281                        // test if the parent has been fully replicated
282                        // if yes, find the next one
283                        while ( ( N_babies ( parent ) ==0 ) || ( N_babies ( parent ) ==1 && parent>i ) ) parent++;
284
285                        // Replicate parent
286                        ind ( i ) = parent;
287
288                        N_babies ( parent ) --; //this index was now replicated;
289                }
290
291        }
292
293        // copy the internals according to ind
294        for ( i=0;i<n;i++ ) {
295                if ( ind ( i ) !=i ) {
296                        samples ( i ) =samples ( ind ( i ) );
297                }
298                w ( i ) = 1.0/n;
299        }
300
301        return ind;
302}
303
304void eEmp::set_statistics ( const vec &w0, const epdf* epdf0 ) {
305        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0");
306        dim = epdf0->dimension();
307        w=w0;
308        w/=sum ( w0 );//renormalize
309        n=w.length();
310        samples.set_size ( n );
311        dim = epdf0->dimension();
312
313        for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();}
314}
315
316void eEmp::set_samples ( const epdf* epdf0 ) {
317        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0");
318        w=1;
319        w/=sum ( w );//renormalize
320
321        for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();}
322}
323
324void migamma_ref::from_setting( const Setting &set ) 
325{                               
326        vec ref;
327        UI::get( ref, set, "ref" );
328        set_parameters(set["k"],ref,set["l"]);
329}
330
331/*void migamma_ref::to_setting( Setting &set ) const
332{       
333        Transport::to_setting( set );
334
335        Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );
336        kilometers_setting = kilometers;
337
338        UI::save( passengers, set, "passengers" );
339}*/
340
341
342void mlognorm::from_setting( const Setting &set ) 
343{       
344        vec mu0;
345        UI::get( mu0, set, "mu0");
346        set_parameters(mu0.length(),set["k"]);
347        condition(mu0);
348}
349
350/*void mlognorm::to_setting( Setting &set ) const
351{       
352        Transport::to_setting( set );
353
354        Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );
355        kilometers_setting = kilometers;
356
357        UI::save( passengers, set, "passengers" );
358}*/
359
360
361};
Note: See TracBrowser for help on using the browser.