root/bdm/stat/libEF.h @ 67

Revision 67, 10.6 kB (checked in by smidl, 16 years ago)

opavy

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