root/bdm/stat/libEF.h @ 262

Revision 262, 23.9 kB (checked in by smidl, 15 years ago)

cleanup of include files

  • 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
17#include "libBM.h"
18#include "../math/chmat.h"
19//#include <std>
20
21namespace bdm{
22
23
24//! Global Uniform_RNG
25extern Uniform_RNG UniRNG;
26//! Global Normal_RNG
27extern Normal_RNG NorRNG;
28//! Global Gamma_RNG
29extern Gamma_RNG GamRNG;
30
31/*!
32* \brief General conjugate exponential family posterior density.
33
34* More?...
35*/
36
37class eEF : public epdf {
38public:
39//      eEF() :epdf() {};
40        //! default constructor
41        eEF ( const RV &rv ) :epdf ( rv ) {};
42        //! logarithm of the normalizing constant, \f$\mathcal{I}\f$
43        virtual double lognc() const =0;
44        //!TODO decide if it is really needed
45        virtual void dupdate ( mat &v ) {it_error ( "Not implemented" );};
46        //!Evaluate normalized log-probability
47        virtual double evallog_nn ( const vec &val ) const{it_error ( "Not implemented" );return 0.0;};
48        //!Evaluate normalized log-probability
49        virtual double evallog ( const vec &val ) const {double tmp;tmp= evallog_nn ( val )-lognc();it_assert_debug(std::isfinite(tmp),"Infinite value"); return tmp;}
50        //!Evaluate normalized log-probability for many samples
51        virtual vec evallog ( const mat &Val ) const {
52                vec x ( Val.cols() );
53                for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evallog_nn ( Val.get_col ( i ) ) ;}
54                return x-lognc();
55        }
56        //!Power of the density, used e.g. to flatten the density
57        virtual void pow ( double p ) {it_error ( "Not implemented" );};
58};
59
60/*!
61* \brief Exponential family model.
62
63* More?...
64*/
65
66class mEF : public mpdf {
67
68public:
69        //! Default constructor
70        mEF ( const RV &rv0, const RV &rvc0 ) :mpdf ( rv0,rvc0 ) {};
71};
72
73//! Estimator for Exponential family
74class BMEF : public BM {
75protected:
76        //! forgetting factor
77        double frg;
78        //! cached value of lognc() in the previous step (used in evaluation of \c ll )
79        double last_lognc;
80public:
81        //! Default constructor
82        BMEF ( const RV &rv, double frg0=1.0 ) :BM ( rv ), frg ( frg0 ) {}
83        //! Copy constructor
84        BMEF ( const BMEF &B ) :BM ( B ), frg ( B.frg ), last_lognc ( B.last_lognc ) {}
85        //!get statistics from another model
86        virtual void set_statistics ( const BMEF* BM0 ) {it_error ( "Not implemented" );};
87        //! Weighted update of sufficient statistics (Bayes rule)
88        virtual void bayes ( const vec &data, const double w ) {};
89        //original Bayes
90        void bayes ( const vec &dt );
91        //!Flatten the posterior according to the given BMEF (of the same type!)
92        virtual void flatten ( const BMEF * B ) {it_error ( "Not implemented" );}
93        //!Flatten the posterior as if to keep nu0 data
94//      virtual void flatten ( double nu0 ) {it_error ( "Not implemented" );}
95
96        BMEF* _copy_ ( bool changerv=false ) {it_error ( "function _copy_ not implemented for this BM" ); return NULL;};
97};
98
99template<class sq_T>
100class mlnorm;
101
102/*!
103* \brief Gaussian density with positive definite (decomposed) covariance matrix.
104
105* More?...
106*/
107template<class sq_T>
108class enorm : public eEF {
109protected:
110        //! mean value
111        vec mu;
112        //! Covariance matrix in decomposed form
113        sq_T R;
114        //! dimension (redundant from rv.count() for easier coding )
115        int dim;
116public:
117        //!Default constructor
118        enorm ( const RV &rv );
119        //! Set mean value \c mu and covariance \c R
120        void set_parameters ( const vec &mu,const sq_T &R );
121        ////! tupdate in exponential form (not really handy)
122        //void tupdate ( double phi, mat &vbar, double nubar );
123        //! dupdate in exponential form (not really handy)
124        void dupdate ( mat &v,double nu=1.0 );
125
126        vec sample() const;
127        //! TODO is it used?
128        mat sample ( int N ) const;
129//      double eval ( const vec &val ) const ;
130        double evallog_nn ( const vec &val ) const;
131        double lognc () const;
132        vec mean() const {return mu;}
133        vec variance() const {return diag(R.to_mat());}
134//      mlnorm<sq_T>* condition ( const RV &rvn ) const ;
135        mpdf* condition ( const RV &rvn ) const ;
136//      enorm<sq_T>* marginal ( const RV &rv ) const;
137        epdf* marginal ( const RV &rv ) const;
138//Access methods
139        //! returns a pointer to the internal mean value. Use with Care!
140        vec& _mu() {return mu;}
141
142        //! access function
143        void set_mu ( const vec mu0 ) { mu=mu0;}
144
145        //! returns pointers to the internal variance and its inverse. Use with Care!
146        sq_T& _R() {return R;}
147        const sq_T& _R() const {return R;}
148
149        //! access method
150//      mat getR () {return R.to_mat();}
151};
152
153/*!
154* \brief Gauss-inverse-Wishart density stored in LD form
155
156* For \f$p\f$-variate densities, given rv.count() should be \f$p\times\f$ V.rows().
157*
158*/
159class egiw : public eEF {
160protected:
161        //! Extended information matrix of sufficient statistics
162        ldmat V;
163        //! Number of data records (degrees of freedom) of sufficient statistics
164        double nu;
165        //! Dimension of the output
166        int xdim;
167        //! Dimension of the regressor
168        int nPsi;
169public:
170        //!Default constructor, if nu0<0 a minimal nu0 will be computed
171        egiw ( RV rv, mat V0, double nu0=-1.0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
172                xdim = rv.count() /V.rows();
173                it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
174                nPsi = V.rows()-xdim;
175                //set mu to have proper normalization and
176                if (nu0<0){
177                        nu = 0.1 +nPsi +2*xdim +2; // +2 assures finite expected value of R
178                        // terms before that are sufficient for finite normalization
179                }
180        }
181        //!Full constructor for V in ldmat form
182        egiw ( RV rv, ldmat V0, double nu0=-1.0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
183                xdim = rv.count() /V.rows();
184                it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
185                nPsi = V.rows()-xdim;
186                if (nu0<0){
187                        nu = 0.1 +nPsi +2*xdim +2; // +2 assures finite expected value of R
188                        // terms before that are sufficient for finite normalization
189                }
190        }
191
192        vec sample() const;
193        vec mean() const;
194        vec variance() const;
195        void mean_mat ( mat &M, mat&R ) const;
196        //! In this instance, val= [theta, r]. For multivariate instances, it is stored columnwise val = [theta_1 theta_2 ... r_1 r_2 ]
197        double evallog_nn ( const vec &val ) const;
198        double lognc () const;
199
200        //Access
201        //! returns a pointer to the internal statistics. Use with Care!
202        ldmat& _V() {return V;}
203        //! returns a pointer to the internal statistics. Use with Care!
204        const ldmat& _V() const {return V;}
205        //! returns a pointer to the internal statistics. Use with Care!
206        double& _nu()  {return nu;}
207        const double& _nu() const {return nu;}
208        void pow ( double p ) {V*=p;nu*=p;};
209};
210
211/*! \brief Dirichlet posterior density
212
213Continuous Dirichlet density of \f$n\f$-dimensional variable \f$x\f$
214\f[
215f(x|\beta) = \frac{\Gamma[\gamma]}{\prod_{i=1}^{n}\Gamma(\beta_i)} \prod_{i=1}^{n}x_i^{\beta_i-1}
216\f]
217where \f$\gamma=\sum_i \beta_i\f$.
218*/
219class eDirich: public eEF {
220protected:
221        //!sufficient statistics
222        vec beta;
223        //!speedup variable
224        double gamma;
225public:
226        //!Default constructor
227        eDirich ( const RV &rv, const vec &beta0 ) : eEF ( rv ),beta ( beta0 ) {it_assert_debug ( rv.count() ==beta.length(),"Incompatible statistics" ); };
228        //! Copy constructor
229        eDirich ( const eDirich &D0 ) : eEF ( D0.rv ),beta ( D0.beta ) {};
230        vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
231        vec mean() const {return beta/gamma;};
232        vec variance() const {return elem_mult(beta,(beta+1))/ (gamma*(gamma+1));}
233        //! In this instance, val is ...
234        double evallog_nn ( const vec &val ) const {double tmp; tmp=( beta-1 ) *log ( val );            it_assert_debug(std::isfinite(tmp),"Infinite value");
235        return tmp;};
236        double lognc () const {
237                double tmp;
238                double gam=sum ( beta );
239                double lgb=0.0;
240                for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
241                tmp= lgb-lgamma ( gam );
242                it_assert_debug(std::isfinite(tmp),"Infinite value");
243                return tmp;
244        };
245        //!access function
246        vec& _beta()  {return beta;}
247        //!Set internal parameters
248        void set_parameters ( const vec &beta0 ) {
249                if ( beta0.length() !=beta.length() ) {
250                        it_assert_debug ( rv.length() ==1,"Undefined" );
251                        rv.set_size ( 0,beta0.length() );
252                }
253                beta= beta0;
254                gamma = sum(beta);
255        }
256};
257
258//! \brief Estimator for Multinomial density
259class multiBM : public BMEF {
260protected:
261        //! Conjugate prior and posterior
262        eDirich est;
263        //! Pointer inside est to sufficient statistics
264        vec &beta;
265public:
266        //!Default constructor
267        multiBM ( const RV &rv, const vec beta0 ) : BMEF ( rv ),est ( rv,beta0 ),beta ( est._beta() ) {if(beta.length()>0){last_lognc=est.lognc();}else{last_lognc=0.0;}}
268        //!Copy constructor
269        multiBM ( const multiBM &B ) : BMEF ( B ),est ( rv,B.beta ),beta ( est._beta() ) {}
270        //! Sets sufficient statistics to match that of givefrom mB0
271        void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
272        void bayes ( const vec &dt ) {
273                if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
274                beta+=dt;
275                if ( evalll ) {ll=est.lognc()-last_lognc;}
276        }
277        double logpred ( const vec &dt ) const {
278                eDirich pred ( est );
279                vec &beta = pred._beta();
280
281                double lll;
282                if ( frg<1.0 )
283                        {beta*=frg;lll=pred.lognc();}
284                else
285                        if ( evalll ) {lll=last_lognc;}
286                        else{lll=pred.lognc();}
287
288                beta+=dt;
289                return pred.lognc()-lll;
290        }
291        void flatten ( const BMEF* B ) {
292                const multiBM* E=dynamic_cast<const multiBM*> ( B );
293                // sum(beta) should be equal to sum(B.beta)
294                const vec &Eb=E->beta;//const_cast<multiBM*> ( E )->_beta();
295                beta*= ( sum ( Eb ) /sum ( beta ) );
296                if ( evalll ) {last_lognc=est.lognc();}
297        }
298        const epdf& _epdf() const {return est;};
299        const eDirich* _e() const {return &est;};
300        void set_parameters ( const vec &beta0 ) {
301                est.set_parameters ( beta0 );
302                rv = est._rv();
303                if ( evalll ) {last_lognc=est.lognc();}
304        }
305};
306
307/*!
308 \brief Gamma posterior density
309
310 Multivariate Gamma density as product of independent univariate densities.
311 \f[
312 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i)
313 \f]
314*/
315
316class egamma : public eEF {
317protected:
318        //! Vector \f$\alpha\f$
319        vec alpha;
320        //! Vector \f$\beta\f$
321        vec beta;
322public :
323        //! Default constructor
324        egamma ( const RV &rv ) :eEF ( rv ), alpha(rv.count()), beta(rv.count()) {};
325        //! Sets parameters
326        void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;};
327        vec sample() const;
328        //! TODO: is it used anywhere?
329//      mat sample ( int N ) const;
330        double evallog ( const vec &val ) const;
331        double lognc () const;
332        //! Returns poiter to alpha and beta. Potentially dengerous: use with care!
333        void _param ( vec* &a, vec* &b ) {a=&alpha;b=&beta;};
334        vec mean() const {return elem_div(alpha,beta);}
335        vec variance() const {return elem_div(alpha,elem_mult(beta,beta)); }
336};
337
338/*!
339 \brief Inverse-Gamma posterior density
340
341 Multivariate inverse-Gamma density as product of independent univariate densities.
342 \f[
343 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i)
344 \f]
345
346 Inverse Gamma can be converted to Gamma using \f[
347 x\sim iG(a,b) => 1/x\sim G(a,1/b)
348\f]
349This relation is used in sampling.
350 */
351
352class eigamma : public eEF {
353        protected:
354        //! Vector \f$\alpha\f$
355                vec* alpha;
356        //! Vector \f$\beta\f$ (in fact it is 1/beta as used in definition of iG)
357                vec* beta;
358                //!internal egamma
359                egamma eg;
360        public :
361        //! Default constructor
362                eigamma ( const RV &rv ) :eEF ( rv ), eg(rv) {eg._param(alpha,beta);};
363        //! Sets parameters
364                void set_parameters ( const vec &a, const vec &b ) {*alpha=a,*beta=b;};
365                vec sample() const {return 1.0/eg.sample();};
366        //! TODO: is it used anywhere?
367//      mat sample ( int N ) const;
368                double evallog ( const vec &val ) const {return eg.evallog(val);};
369                double lognc () const {return eg.lognc();};
370        //! Returns poiter to alpha and beta. Potentially dangerous: use with care!
371                void _param ( vec* &a, vec* &b ) {a=alpha;b=beta;};
372                vec mean() const {return elem_div(*beta,*alpha-1);}
373                vec variance() const {vec mea=mean(); return elem_div(elem_mult(mea,mea),*alpha-2);}
374};
375/*
376//! Weighted mixture of epdfs with external owned components.
377class emix : public epdf {
378protected:
379        int n;
380        vec &w;
381        Array<epdf*> Coms;
382public:
383//! Default constructor
384        emix ( const RV &rv, vec &w0): epdf(rv), n(w0.length()), w(w0), Coms(n) {};
385        void set_parameters( int &i, double wi, epdf* ep){w(i)=wi;Coms(i)=ep;}
386        vec mean(){vec pom; for(int i=0;i<n;i++){pom+=Coms(i)->mean()*w(i);} return pom;};
387        vec sample() {it_error ( "Not implemented" );return 0;}
388};
389*/
390
391//!  Uniform distributed density on a rectangular support
392
393class euni: public epdf {
394protected:
395//! lower bound on support
396        vec low;
397//! upper bound on support
398        vec high;
399//! internal
400        vec distance;
401//! normalizing coefficients
402        double nk;
403//! cache of log( \c nk )
404        double lnk;
405public:
406        //! Defualt constructor
407        euni ( const RV rv ) :epdf ( rv ) {}
408        double eval ( const vec &val ) const  {return nk;}
409        double evallog ( const vec &val ) const  {return lnk;}
410        vec sample() const {
411                vec smp ( rv.count() );
412#pragma omp critical
413                UniRNG.sample_vector ( rv.count(),smp );
414                return low+elem_mult ( distance,smp );
415        }
416        //! set values of \c low and \c high
417        void set_parameters ( const vec &low0, const vec &high0 ) {
418                distance = high0-low0;
419                it_assert_debug ( min ( distance ) >0.0,"bad support" );
420                low = low0;
421                high = high0;
422                nk = prod ( 1.0/distance );
423                lnk = log ( nk );
424        }
425        vec mean() const {return (high-low)/2.0;}
426        vec variance() const {return (pow(high,2)+pow(low,2)+elem_mult(high,low))/3.0;}
427};
428
429
430/*!
431 \brief Normal distributed linear function with linear function of mean value;
432
433 Mean value \f$mu=A*rvc+mu_0\f$.
434*/
435template<class sq_T>
436class mlnorm : public mEF {
437protected:
438        //! Internal epdf that arise by conditioning on \c rvc
439        enorm<sq_T> epdf;
440        mat A;
441        vec mu_const;
442        vec& _mu; //cached epdf.mu;
443public:
444        //! Constructor
445        mlnorm ( const RV &rv, const RV &rvc );
446        //! Set \c A and \c R
447        void set_parameters ( const  mat &A, const vec &mu0, const sq_T &R );
448//      //!Generate one sample of the posterior
449//      vec samplecond (const vec &cond, double &lik );
450//      //!Generate matrix of samples of the posterior
451//      mat samplecond (const vec &cond, vec &lik, int n );
452        //! Set value of \c rvc . Result of this operation is stored in \c epdf use function \c _ep to access it.
453        void condition ( const vec &cond );
454
455        //!access function
456        vec& _mu_const() {return mu_const;}
457        //!access function
458        mat& _A() {return A;}
459        //!access function
460        mat _R() {return epdf._R().to_mat();}
461
462        template<class sq_M>
463        friend std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_M> &ml );
464};
465
466/*! (Approximate) Student t density with linear function of mean value
467
468The internal epdf of this class is of the type of a Gaussian (enorm).
469However, each conditioning is trying to assure the best possible approximation by taking into account the zeta function. See [] for reference.
470
471Perhaps a moment-matching technique?
472*/
473class mlstudent : public mlnorm<ldmat> {
474protected:
475        ldmat Lambda;
476        ldmat &_R;
477        ldmat Re;
478public:
479        mlstudent ( const RV &rv0, const RV &rvc0 ) :mlnorm<ldmat> ( rv0,rvc0 ),
480                        Lambda ( rv0.count() ),
481                        _R ( epdf._R() ) {}
482        void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0) {
483                epdf.set_parameters ( zeros ( rv.count() ),Lambda );
484                A = A0;
485                mu_const = mu0;
486                Re=R0;
487                Lambda = Lambda0;
488        }
489        void condition ( const vec &cond ) {
490                _mu = A*cond + mu_const;
491                double zeta;
492                //ugly hack!
493                if ((cond.length()+1)==Lambda.rows()){
494                        zeta = Lambda.invqform ( concat(cond, vec_1(1.0)) );
495                } else {
496                        zeta = Lambda.invqform ( cond );
497                }
498                _R = Re;
499                _R*=( 1+zeta );// / ( nu ); << nu is in Re!!!!!!
500        };
501
502};
503/*!
504\brief  Gamma random walk
505
506Mean value, \f$\mu\f$, of this density is given by \c rvc .
507Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
508This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
509
510The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
511*/
512class mgamma : public mEF {
513protected:
514        //! Internal epdf that arise by conditioning on \c rvc
515        egamma epdf;
516        //! Constant \f$k\f$
517        double k;
518        //! cache of epdf.beta
519        vec* _beta;
520
521public:
522        //! Constructor
523        mgamma ( const RV &rv,const RV &rvc ): mEF ( rv,rvc ), epdf ( rv ) {vec* tmp; epdf._param ( tmp,_beta );ep=&epdf;};
524        //! Set value of \c k
525        void set_parameters ( double k );
526        void condition ( const vec &val ) {*_beta=k/val;};
527};
528
529/*!
530\brief  Inverse-Gamma random walk
531
532Mean value, \f$\mu\f$, of this density is given by \c rvc .
533Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
534This is achieved by setting \f$\alpha=\mu/k+2\f$ and \f$\beta=\mu(\alpha-1)\f$.
535
536The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
537 */
538class migamma : public mEF {
539        protected:
540        //! Internal epdf that arise by conditioning on \c rvc
541                eigamma epdf;
542        //! Constant \f$k\f$
543                double k;
544        //! cache of epdf.beta
545                vec* _beta;
546                //! chaceh of epdf.alpha
547                vec* _alpha;
548
549        public:
550        //! Constructor
551                migamma ( const RV &rv,const RV &rvc ): mEF ( rv,rvc ), epdf ( rv ) {epdf._param ( _alpha,_beta );ep=&epdf;};
552        //! Set value of \c k
553                void set_parameters ( double k0 ){k=k0;*_alpha=1.0/(k*k)+2;};
554                void condition ( const vec &val ) {
555                        *_beta=elem_mult(val,(*_alpha-1));
556                };
557};
558
559/*!
560\brief  Gamma random walk around a fixed point
561
562Mean 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
563\f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
564
565Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
566This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
567
568The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
569*/
570class mgamma_fix : public mgamma {
571protected:
572        //! parameter l
573        double l;
574        //! reference vector
575        vec refl;
576public:
577        //! Constructor
578        mgamma_fix ( const RV &rv,const RV &rvc ) : mgamma ( rv,rvc ),refl ( rv.count() ) {};
579        //! Set value of \c k
580        void set_parameters ( double k0 , vec ref0, double l0 ) {
581                mgamma::set_parameters ( k0 );
582                refl=pow ( ref0,1.0-l0 );l=l0;
583        };
584
585        void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); *_beta=k/mean;};
586};
587
588
589/*!
590\brief  Inverse-Gamma random walk around a fixed point
591
592Mean 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
593\f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
594
595==== Check == vv =
596Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
597This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
598
599The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
600 */
601class migamma_fix : public migamma {
602        protected:
603        //! parameter l
604                double l;
605        //! reference vector
606                vec refl;
607        public:
608        //! Constructor
609                migamma_fix ( const RV &rv,const RV &rvc ) : migamma ( rv,rvc ),refl ( rv.count() ) {};
610        //! Set value of \c k
611                void set_parameters ( double k0 , vec ref0, double l0 ) {
612                        migamma::set_parameters ( k0 );
613                        refl=pow ( ref0,1.0-l0 );l=l0;
614                };
615
616                void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); migamma::condition(mean);};
617};
618//! Switch between various resampling methods.
619enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
620/*!
621\brief Weighted empirical density
622
623Used e.g. in particle filters.
624*/
625class eEmp: public epdf {
626protected :
627        //! Number of particles
628        int n;
629        //! Sample weights \f$w\f$
630        vec w;
631        //! Samples \f$x^{(i)}, i=1..n\f$
632        Array<vec> samples;
633public:
634        //! Default constructor
635        eEmp ( const RV &rv0 ,int n0 ) :epdf ( rv0 ),n ( n0 ),w ( n ),samples ( n ) {};
636        //! Set samples and weights
637        void set_parameters ( const vec &w0, const epdf* pdf0 );
638        //! Set sample
639        void set_samples ( const epdf* pdf0 );
640        //! Set sample
641        void set_n ( int n0, bool copy=true ){w.set_size(n0,copy);samples.set_size(n0,copy);};
642        //! Potentially dangerous, use with care.
643        vec& _w()  {return w;};
644        //! Potentially dangerous, use with care.
645        const vec& _w() const {return w;};
646        //! access function
647        Array<vec>& _samples() {return samples;};
648        //! access function
649        const Array<vec>& _samples() const {return samples;};
650        //! 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.
651        ivec resample ( RESAMPLING_METHOD method = SYSTEMATIC );
652        //! inherited operation : NOT implemneted
653        vec sample() const {it_error ( "Not implemented" );return 0;}
654        //! inherited operation : NOT implemneted
655        double evallog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
656        vec mean() const {
657                vec pom=zeros ( rv.count() );
658                for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
659                return pom;
660        }
661        vec variance() const {
662                vec pom=zeros ( rv.count() );
663                for ( int i=0;i<n;i++ ) {pom+=pow(samples ( i ),2) *w ( i );}
664                return pom-pow(mean(),2);
665        }
666};
667
668
669////////////////////////
670
671template<class sq_T>
672enorm<sq_T>::enorm ( const RV &rv ) :eEF ( rv ), mu ( rv.count() ),R ( rv.count() ),dim ( rv.count() ) {};
673
674template<class sq_T>
675void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
676//Fixme test dimensions of mu0 and R0;
677        mu = mu0;
678        R = R0;
679};
680
681template<class sq_T>
682void enorm<sq_T>::dupdate ( mat &v, double nu ) {
683        //
684};
685
686// template<class sq_T>
687// void enorm<sq_T>::tupdate ( double phi, mat &vbar, double nubar ) {
688//      //
689// };
690
691template<class sq_T>
692vec enorm<sq_T>::sample() const {
693        vec x ( dim );
694        #pragma omp critical
695        NorRNG.sample_vector ( dim,x );
696        vec smp = R.sqrt_mult ( x );
697
698        smp += mu;
699        return smp;
700};
701
702template<class sq_T>
703mat enorm<sq_T>::sample ( int N ) const {
704        mat X ( dim,N );
705        vec x ( dim );
706        vec pom;
707        int i;
708
709        for ( i=0;i<N;i++ ) {
710        #pragma omp critical
711                NorRNG.sample_vector ( dim,x );
712                pom = R.sqrt_mult ( x );
713                pom +=mu;
714                X.set_col ( i, pom );
715        }
716
717        return X;
718};
719
720// template<class sq_T>
721// double enorm<sq_T>::eval ( const vec &val ) const {
722//      double pdfl,e;
723//      pdfl = evallog ( val );
724//      e = exp ( pdfl );
725//      return e;
726// };
727
728template<class sq_T>
729double enorm<sq_T>::evallog_nn ( const vec &val ) const {
730        // 1.83787706640935 = log(2pi)
731        double tmp=-0.5* ( R.invqform ( mu-val ) );// - lognc();
732        return  tmp;
733};
734
735template<class sq_T>
736inline double enorm<sq_T>::lognc () const {
737        // 1.83787706640935 = log(2pi)
738        double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
739        return tmp;
740};
741
742template<class sq_T>
743mlnorm<sq_T>::mlnorm ( const RV &rv0, const RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu ( epdf._mu() ) {
744        ep =&epdf;
745}
746
747template<class sq_T>
748void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 ) {
749        epdf.set_parameters ( zeros ( rv.count() ),R0 );
750        A = A0;
751        mu_const = mu0;
752}
753
754// template<class sq_T>
755// vec mlnorm<sq_T>::samplecond (const  vec &cond, double &lik ) {
756//      this->condition ( cond );
757//      vec smp = epdf.sample();
758//      lik = epdf.eval ( smp );
759//      return smp;
760// }
761
762// template<class sq_T>
763// mat mlnorm<sq_T>::samplecond (const vec &cond, vec &lik, int n ) {
764//      int i;
765//      int dim = rv.count();
766//      mat Smp ( dim,n );
767//      vec smp ( dim );
768//      this->condition ( cond );
769//
770//      for ( i=0; i<n; i++ ) {
771//              smp = epdf.sample();
772//              lik ( i ) = epdf.eval ( smp );
773//              Smp.set_col ( i ,smp );
774//      }
775//
776//      return Smp;
777// }
778
779template<class sq_T>
780void mlnorm<sq_T>::condition ( const vec &cond ) {
781        _mu = A*cond + mu_const;
782//R is already assigned;
783}
784
785template<class sq_T>
786epdf* enorm<sq_T>::marginal ( const RV &rvn ) const {
787        ivec irvn = rvn.dataind ( rv );
788
789        sq_T Rn ( R,irvn );
790        enorm<sq_T>* tmp = new enorm<sq_T> ( rvn );
791        tmp->set_parameters ( mu ( irvn ), Rn );
792        return tmp;
793}
794
795template<class sq_T>
796mpdf* enorm<sq_T>::condition ( const RV &rvn ) const {
797
798        RV rvc = rv.subt ( rvn );
799        it_assert_debug ( ( rvc.count() +rvn.count() ==rv.count() ),"wrong rvn" );
800        //Permutation vector of the new R
801        ivec irvn = rvn.dataind ( rv );
802        ivec irvc = rvc.dataind ( rv );
803        ivec perm=concat ( irvn , irvc );
804        sq_T Rn ( R,perm );
805
806        //fixme - could this be done in general for all sq_T?
807        mat S=Rn.to_mat();
808        //fixme
809        int n=rvn.count()-1;
810        int end=R.rows()-1;
811        mat S11 = S.get ( 0,n, 0, n );
812        mat S12 = S.get ( 0, n , rvn.count(), end );
813        mat S22 = S.get ( rvn.count(), end, rvn.count(), end );
814
815        vec mu1 = mu ( irvn );
816        vec mu2 = mu ( irvc );
817        mat A=S12*inv ( S22 );
818        sq_T R_n ( S11 - A *S12.T() );
819
820        mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( rvn,rvc );
821
822        tmp->set_parameters ( A,mu1-A*mu2,R_n );
823        return tmp;
824}
825
826///////////
827
828template<class sq_T>
829std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_T> &ml ) {
830        os << "A:"<< ml.A<<endl;
831        os << "mu:"<< ml.mu_const<<endl;
832        os << "R:" << ml.epdf._R().to_mat() <<endl;
833        return os;
834};
835
836}
837#endif //EF_H
Note: See TracBrowser for help on using the browser.