root/bdm/stat/libEF.h @ 256

Revision 256, 23.8 kB (checked in by smidl, 15 years ago)

uibuilder works (again)

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