root/bdm/stat/libEF.h @ 85

Revision 85, 10.2 kB (checked in by smidl, 16 years ago)

compilation and documantation fixes

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