root/bdm/stat/libEF.h @ 129

Revision 129, 11.3 kB (checked in by smidl, 16 years ago)

preklad na aligatoru

  • Property svn:eol-style set to native
Line 
1/*!
2  \file
3  \brief Probability distributions for Exponential Family models.
4  \author Vaclav Smidl.
5
6  -----------------------------------
7  BDM++ - C++ library for Bayesian Decision Making under Uncertainty
8
9  Using IT++ for numerical operations
10  -----------------------------------
11*/
12
13#ifndef EF_H
14#define EF_H
15
16#include <itpp/itbase.h>
17#include "../math/libDC.h"
18#include "libBM.h"
19#include "../itpp_ext.h"
20//#include <std>
21
22using namespace itpp;
23
24
25//! Global Uniform_RNG
26extern Uniform_RNG UniRNG;
27//! Global Normal_RNG
28extern Normal_RNG NorRNG;
29//! Global Gamma_RNG
30extern Gamma_RNG GamRNG;
31
32/*!
33* \brief General conjugate exponential family posterior density.
34
35* More?...
36*/
37
38class eEF : public epdf {
39public:
40//      eEF() :epdf() {};
41        //! default constructor
42        eEF ( const RV &rv ) :epdf ( rv ) {};
43        //! logarithm of the normalizing constant, \f$\mathcal{I}\f$
44        virtual double lognc()const =0;
45        //!TODO decide if it is really needed
46        virtual void tupdate ( double phi, mat &vbar, double nubar ) {};
47        //!TODO decide if it is really needed
48        virtual void dupdate ( mat &v,double nu=1.0 ) {};
49};
50
51/*!
52* \brief Exponential family model.
53
54* More?...
55*/
56
57class mEF : public mpdf {
58
59public:
60        //! Default constructor
61        mEF ( const RV &rv0, const RV &rvc0 ) :mpdf ( rv0,rvc0 ) {};
62};
63
64/*!
65* \brief Gaussian density with positive definite (decomposed) covariance matrix.
66
67* More?...
68*/
69template<class sq_T>
70
71class enorm : public eEF {
72protected:
73        //! mean value
74        vec mu;
75        //! Covariance matrix in decomposed form
76        sq_T R;
77        //! dimension (redundant from rv.count() for easier coding )
78        int dim;
79public:
80//      enorm() :eEF() {};
81        //!Default constructor
82        enorm ( RV &rv );
83        //! Set mean value \c mu and covariance \c R
84        void set_parameters ( const vec &mu,const sq_T &R );
85        //! tupdate in exponential form (not really handy)
86        void tupdate ( double phi, mat &vbar, double nubar );
87        //! dupdate in exponential form (not really handy)
88        void dupdate ( mat &v,double nu=1.0 );
89
90        vec sample() const;
91        //! TODO is it used?
92        mat sample ( int N ) const;
93        double eval ( const vec &val ) const ;
94        double evalpdflog ( const vec &val ) const;
95        double lognc () const;
96        vec mean() const {return mu;}
97
98//Access methods
99        //! returns a pointer to the internal mean value. Use with Care!
100        vec& _mu() {return mu;}
101       
102        //! access function
103        void set_mu(const vec mu0) { mu=mu0;}
104
105        //! returns pointers to the internal variance and its inverse. Use with Care!
106        sq_T& _R() {return R;}
107
108        //! access method
109        mat getR () {return R.to_mat();}
110};
111
112/*!
113* \brief Gauss-inverse-Wishart density stored in LD form
114
115* More?...
116*/
117class egiw : public eEF {
118protected:
119        //! Extended information matrix of sufficient statistics
120        ldmat V;
121        //! Number of data records (degrees of freedom) of sufficient statistics
122        double nu;
123public:
124        //!Default constructor
125        egiw(RV rv, mat V0, double nu0): eEF(rv), V(V0), nu(nu0) {
126                it_assert_debug(rv.count()==V.rows(),"Incompatible V0.");
127        }
128
129        vec sample() const;
130        vec mean() const;
131        double evalpdflog ( const vec &val ) const;
132        double lognc () const;
133
134        //Access
135        //! returns a pointer to the internal statistics. Use with Care!
136        ldmat& _V() {return V;}
137        //! returns a pointer to the internal statistics. Use with Care!
138        double& _nu() {return nu;}
139
140};
141
142/*!
143 \brief Gamma posterior density
144
145 Multvariate Gamma density as product of independent univariate densities.
146 \f[
147 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i)
148 \f]
149*/
150
151class egamma : public eEF {
152protected:
153        //! Vector \f$\alpha\f$
154        vec alpha;
155        //! Vector \f$\beta\f$
156        vec beta;
157public :
158        //! Default constructor
159        egamma ( const RV &rv ) :eEF ( rv ) {};
160        //! Sets parameters
161        void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;};
162        vec sample() const;
163        //! TODO: is it used anywhere?
164//      mat sample ( int N ) const;
165        double evalpdflog ( const vec &val ) const;
166        double lognc () const;
167        //! Returns poiter to alpha and beta. Potentially dengerous: use with care!
168        void _param ( vec* &a, vec* &b ) {a=&alpha;b=&beta;};
169        vec mean() const {vec pom ( alpha ); pom/=beta; return pom;}
170};
171/*
172//! Weighted mixture of epdfs with external owned components.
173class emix : public epdf {
174protected:
175        int n;
176        vec &w;
177        Array<epdf*> Coms;
178public:
179//! Default constructor
180        emix ( const RV &rv, vec &w0): epdf(rv), n(w0.length()), w(w0), Coms(n) {};
181        void set_parameters( int &i, double wi, epdf* ep){w(i)=wi;Coms(i)=ep;}
182        vec mean(){vec pom; for(int i=0;i<n;i++){pom+=Coms(i)->mean()*w(i);} return pom;};
183        vec sample() {it_error ( "Not implemented" );return 0;}
184};
185*/
186
187//!  Uniform distributed density on a rectangular support
188
189class euni: public epdf {
190protected:
191//! lower bound on support
192        vec low;
193//! upper bound on support
194        vec high;
195//! internal
196        vec distance;
197//! normalizing coefficients
198        double nk;
199//! cache of log( \c nk )
200        double lnk;
201public:
202        //! Defualt constructor
203        euni ( const RV rv ) :epdf ( rv ) {}
204        double eval ( const vec &val ) const  {return nk;}
205        double evalpdflog ( const vec &val ) const  {return lnk;}
206        vec sample() const {
207                vec smp ( rv.count() ); 
208                #pragma omp critical
209                UniRNG.sample_vector ( rv.count(),smp );
210                return low+elem_mult(distance,smp);
211        }
212        //! set values of \c low and \c high
213        void set_parameters ( const vec &low0, const vec &high0 ) {
214                distance = high0-low0;
215                it_assert_debug ( min ( distance ) >0.0,"bad support" );
216                low = low0;
217                high = high0;
218                nk = prod ( 1.0/distance );
219                lnk = log ( nk );
220        }
221        vec mean() const {vec pom=high; pom-=low; pom/=2.0; return pom;}
222};
223
224
225/*!
226 \brief Normal distributed linear function with linear function of mean value;
227
228 Mean value \f$mu=A*rvc\f$.
229*/
230template<class sq_T>
231class mlnorm : public mEF {
232        //! Internal epdf that arise by conditioning on \c rvc
233        enorm<sq_T> epdf;
234        mat A;
235        vec& _mu; //cached epdf.mu;
236public:
237        //! Constructor
238        mlnorm ( RV &rv,RV &rvc );
239        //! Set \c A and \c R
240        void set_parameters ( const  mat &A, const sq_T &R );
241        //!Generate one sample of the posterior
242        vec samplecond ( vec &cond, double &lik );
243        //!Generate matrix of samples of the posterior
244        mat samplecond ( vec &cond, vec &lik, int n );
245        //! Set value of \c rvc . Result of this operation is stored in \c epdf use function \c _ep to access it.
246        void condition ( vec &cond );
247};
248
249/*!
250\brief  Gamma random walk
251
252Mean value, \f$\mu\f$, of this density is given by \c rvc .
253Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
254This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
255
256The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
257*/
258class mgamma : public mEF {
259protected:
260        //! Internal epdf that arise by conditioning on \c rvc
261        egamma epdf;
262        //! Constant \f$k\f$
263        double k;
264        //! cache of epdf.beta
265        vec* _beta;
266
267public:
268        //! Constructor
269        mgamma ( const RV &rv,const RV &rvc );
270        //! Set value of \c k
271        void set_parameters ( double k );
272        //!Generate one sample of the posterior
273        vec samplecond ( vec &cond, double &lik );
274        //!Generate matrix of samples of the posterior
275        mat samplecond ( vec &cond, vec &lik, int n );
276        void condition ( const vec &val ) {*_beta=k/val;};
277};
278
279/*!
280\brief  Gamma random walk around a fixed point
281
282Mean value, \f$\mu\f$, of this density is given by a geometric combination of \c rvc and given fixed point, \f$p\f$. \f$l\f$ is the coefficient of the geometric combimation
283\f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
284
285Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
286This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
287
288The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
289*/
290class mgamma_fix : public mgamma {
291protected:
292        //! parameter l
293        double l;
294        //! reference vector
295        vec refl;
296public:
297        //! Constructor
298        mgamma_fix ( const RV &rv,const RV &rvc ) : mgamma ( rv,rvc ),refl ( rv.count() ) {};
299        //! Set value of \c k
300        void set_parameters ( double k0 , vec ref0, double l0 ) {
301                mgamma::set_parameters ( k0 );
302                refl=pow ( ref0,1.0-l0 );l=l0;
303        };
304
305        void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); *_beta=k/mean;};
306};
307
308//! Switch between various resampling methods.
309enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
310/*!
311\brief Weighted empirical density
312
313Used e.g. in particle filters.
314*/
315class eEmp: public epdf {
316protected :
317        //! Number of particles
318        int n;
319        //! Sample weights \f$w\f$
320        vec w;
321        //! Samples \f$x^{(i)}, i=1..n\f$
322        Array<vec> samples;
323public:
324        //! Default constructor
325        eEmp ( const RV &rv0 ,int n0 ) :epdf ( rv0 ),n ( n0 ),w ( n ),samples ( n ) {};
326        //! Set sample
327        void set_parameters ( const vec &w0, epdf* pdf0 );
328        //! Potentially dangerous, use with care.
329        vec& _w()  {return w;};
330        //! access function
331        Array<vec>& _samples() {return samples;};
332        //! Function performs resampling, i.e. removal of low-weight samples and duplication of high-weight samples such that the new samples represent the same density.
333        ivec resample ( RESAMPLING_METHOD method = SYSTEMATIC );
334        //! inherited operation : NOT implemneted
335        vec sample() const {it_error ( "Not implemented" );return 0;}
336        //! inherited operation : NOT implemneted
337        double evalpdflog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
338        vec mean() const {
339                vec pom=zeros ( rv.count() );
340                for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
341                return pom;
342        }
343};
344
345
346////////////////////////
347
348template<class sq_T>
349enorm<sq_T>::enorm ( RV &rv ) :eEF ( rv ), mu ( rv.count() ),R ( rv.count() ),dim ( rv.count() ) {};
350
351template<class sq_T>
352void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
353//Fixme test dimensions of mu0 and R0;
354        mu = mu0;
355        R = R0;
356};
357
358template<class sq_T>
359void enorm<sq_T>::dupdate ( mat &v, double nu ) {
360        //
361};
362
363template<class sq_T>
364void enorm<sq_T>::tupdate ( double phi, mat &vbar, double nubar ) {
365        //
366};
367
368template<class sq_T>
369vec enorm<sq_T>::sample() const {
370        vec x ( dim );
371        NorRNG.sample_vector ( dim,x );
372        vec smp = R.sqrt_mult ( x );
373
374        smp += mu;
375        return smp;
376};
377
378template<class sq_T>
379mat enorm<sq_T>::sample ( int N ) const {
380        mat X ( dim,N );
381        vec x ( dim );
382        vec pom;
383        int i;
384
385        for ( i=0;i<N;i++ ) {
386                NorRNG.sample_vector ( dim,x );
387                pom = R.sqrt_mult ( x );
388                pom +=mu;
389                X.set_col ( i, pom );
390        }
391
392        return X;
393};
394
395template<class sq_T>
396double enorm<sq_T>::eval ( const vec &val ) const {
397        double pdfl,e;
398        pdfl = evalpdflog ( val );
399        e = exp ( pdfl );
400        return e;
401};
402
403template<class sq_T>
404double enorm<sq_T>::evalpdflog ( const vec &val ) const {
405        // 1.83787706640935 = log(2pi)
406        return  -0.5* (  +R.invqform ( mu-val ) ) - lognc();
407};
408
409template<class sq_T>
410inline double enorm<sq_T>::lognc () const {
411        // 1.83787706640935 = log(2pi)
412        return -0.5* ( R.cols() * 1.83787706640935 +R.logdet());
413};
414
415template<class sq_T>
416mlnorm<sq_T>::mlnorm ( RV &rv0,RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu(epdf._mu()) { ep =&epdf;
417}
418
419template<class sq_T>
420void mlnorm<sq_T>::set_parameters ( const mat &A0, const sq_T &R0 ) {
421        epdf.set_parameters ( zeros ( rv.count() ),R0 );
422        A = A0;
423}
424
425template<class sq_T>
426vec mlnorm<sq_T>::samplecond ( vec &cond, double &lik ) {
427        this->condition ( cond );
428        vec smp = epdf.sample();
429        lik = epdf.eval ( smp );
430        return smp;
431}
432
433template<class sq_T>
434mat mlnorm<sq_T>::samplecond ( vec &cond, vec &lik, int n ) {
435        int i;
436        int dim = rv.count();
437        mat Smp ( dim,n );
438        vec smp ( dim );
439        this->condition ( cond );
440
441        for ( i=0; i<n; i++ ) {
442                smp = epdf.sample();
443                lik ( i ) = epdf.eval ( smp );
444                Smp.set_col ( i ,smp );
445        }
446
447        return Smp;
448}
449
450template<class sq_T>
451void mlnorm<sq_T>::condition ( vec &cond ) {
452        _mu = A*cond;
453//R is already assigned;
454}
455
456///////////
457
458
459#endif //EF_H
Note: See TracBrowser for help on using the browser.