root/bdm/stat/libEF.h @ 285

Revision 285, 25.3 kB (checked in by smidl, 15 years ago)

unit-step experiment TR2245p

  • 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 ( ) :epdf ( ) {};
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 ( ) :mpdf ( ) {};
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 (=empty constructor)
82        BMEF ( double frg0=1.0 ) :BM ( ), 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 ) const {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;
114public:
115        //!\name Constructors
116        //!@{
117
118        enorm ( ) :eEF ( ), mu ( ),R ( ) {};
119        enorm ( const vec &mu,const sq_T &R ) {set_parameters ( mu,R );}
120        void set_parameters ( const vec &mu,const sq_T &R );
121        //!@}
122
123        //! \name Mathematical operations
124        //!@{
125
126        //! dupdate in exponential form (not really handy)
127        void dupdate ( mat &v,double nu=1.0 );
128
129        vec sample() const;
130        mat sample ( int N ) 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        //!@}
140
141        //! \name Access to attributes
142        //!@{
143
144        vec& _mu() {return mu;}
145        void set_mu ( const vec mu0 ) { mu=mu0;}
146        sq_T& _R() {return R;}
147        const sq_T& _R() const {return R;}
148        //!@}
149
150};
151
152/*!
153* \brief Gauss-inverse-Wishart density stored in LD form
154
155* For \f$p\f$-variate densities, given rv.count() should be \f$p\times\f$ V.rows().
156*
157*/
158class egiw : public eEF {
159protected:
160        //! Extended information matrix of sufficient statistics
161        ldmat V;
162        //! Number of data records (degrees of freedom) of sufficient statistics
163        double nu;
164        //! Dimension of the output
165        int dimx;
166        //! Dimension of the regressor
167        int nPsi;
168public:
169        //!\name Constructors
170        //!@{
171        egiw() :eEF() {};
172        egiw ( int dimx0, ldmat V0, double nu0=-1.0 ) :eEF() {set_parameters ( dimx0,V0, nu0 );};
173
174        void set_parameters ( int dimx0, ldmat V0, double nu0=-1.0 ) {
175                dimx=dimx0;
176                nPsi = V0.rows()-dimx;
177                dim = dimx* ( dimx+nPsi ); // size(R) + size(Theta)
178
179                V=V0;
180                if ( nu0<0 ) {
181                        nu = 0.1 +nPsi +2*dimx +2; // +2 assures finite expected value of R
182                        // terms before that are sufficient for finite normalization
183                }
184                else {
185                        nu=nu0;
186                }
187        }
188        //!@}
189
190        vec sample() const;
191        vec mean() const;
192        vec variance() const;
193        void mean_mat ( mat &M, mat&R ) const;
194        //! In this instance, val= [theta, r]. For multivariate instances, it is stored columnwise val = [theta_1 theta_2 ... r_1 r_2 ]
195        double evallog_nn ( const vec &val ) const;
196        double lognc () const;
197        void pow ( double p ) {V*=p;nu*=p;};
198
199        //! \name Access attributes
200        //!@{
201
202        ldmat& _V() {return V;}
203        const ldmat& _V() const {return V;}
204        double& _nu()  {return nu;}
205        const double& _nu() const {return nu;}
206        //!@}
207};
208
209/*! \brief Dirichlet posterior density
210
211Continuous Dirichlet density of \f$n\f$-dimensional variable \f$x\f$
212\f[
213f(x|\beta) = \frac{\Gamma[\gamma]}{\prod_{i=1}^{n}\Gamma(\beta_i)} \prod_{i=1}^{n}x_i^{\beta_i-1}
214\f]
215where \f$\gamma=\sum_i \beta_i\f$.
216*/
217class eDirich: public eEF {
218protected:
219        //!sufficient statistics
220        vec beta;
221        //!speedup variable
222        double gamma;
223public:
224        //!\name Constructors
225        //!@{
226
227        eDirich () : eEF ( ) {};
228        eDirich ( const eDirich &D0 ) : eEF () {set_parameters ( D0.beta );};
229        eDirich ( const vec &beta0 ) {set_parameters ( beta0 );};
230        void set_parameters ( const vec &beta0 ) {
231                beta= beta0;
232                dim = beta.length();
233                gamma = sum ( beta );
234        }
235        //!@}
236
237        vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
238        vec mean() const {return beta/gamma;};
239        vec variance() const {return elem_mult ( beta, ( beta+1 ) ) / ( gamma* ( gamma+1 ) );}
240        //! In this instance, val is ...
241        double evallog_nn ( const vec &val ) const {
242                double tmp; tmp= ( beta-1 ) *log ( val );               it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
243                return tmp;
244        };
245        double lognc () const {
246                double tmp;
247                double gam=sum ( beta );
248                double lgb=0.0;
249                for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
250                tmp= lgb-lgamma ( gam );
251                it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
252                return tmp;
253        };
254        //!access function
255        vec& _beta()  {return beta;}
256        //!Set internal parameters
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 ( ) : BMEF ( ),est ( ),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 ( B.est ),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& posterior() const {return est;};
300        const eDirich* _e() const {return &est;};
301        void set_parameters ( const vec &beta0 ) {
302                est.set_parameters ( beta0 );
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        //! \name Constructors
324        //!@{
325        egamma ( ) :eEF ( ), alpha(0), beta(0) {};
326        egamma ( const vec &a, const vec &b ) {set_parameters ( a, b );};
327        void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;dim = alpha.length();};
328        //!@}
329
330        vec sample() const;
331        //! TODO: is it used anywhere?
332//      mat sample ( int N ) const;
333        double evallog ( const vec &val ) const;
334        double lognc () const;
335        //! Returns poiter to alpha and beta. Potentially dengerous: use with care!
336        vec& _alpha() {return alpha;}
337        vec& _beta() {return beta;}
338        vec mean() const {return elem_div ( alpha,beta );}
339        vec variance() const {return elem_div ( alpha,elem_mult ( beta,beta ) ); }
340};
341
342/*!
343 \brief Inverse-Gamma posterior density
344
345 Multivariate inverse-Gamma density as product of independent univariate densities.
346 \f[
347 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i)
348 \f]
349
350Vector \f$\beta\f$ has different meaning (in fact it is 1/beta as used in definition of iG)
351
352 Inverse Gamma can be converted to Gamma using \f[
353 x\sim iG(a,b) => 1/x\sim G(a,1/b)
354\f]
355This relation is used in sampling.
356 */
357
358class eigamma : public egamma {
359protected:
360public :
361        //! \name Constructors
362        //! All constructors are inherited
363        //!@{
364        //!@}
365
366        vec sample() const {return 1.0/egamma::sample();};
367        //! Returns poiter to alpha and beta. Potentially dangerous: use with care!
368        vec mean() const {return elem_div ( beta,alpha-1 );}
369        vec variance() const {vec mea=mean(); return elem_div ( elem_mult ( mea,mea ),alpha-2 );}
370};
371/*
372//! Weighted mixture of epdfs with external owned components.
373class emix : public epdf {
374protected:
375        int n;
376        vec &w;
377        Array<epdf*> Coms;
378public:
379//! Default constructor
380        emix ( const RV &rv, vec &w0): epdf(rv), n(w0.length()), w(w0), Coms(n) {};
381        void set_parameters( int &i, double wi, epdf* ep){w(i)=wi;Coms(i)=ep;}
382        vec mean(){vec pom; for(int i=0;i<n;i++){pom+=Coms(i)->mean()*w(i);} return pom;};
383        vec sample() {it_error ( "Not implemented" );return 0;}
384};
385*/
386
387//!  Uniform distributed density on a rectangular support
388
389class euni: public epdf {
390protected:
391//! lower bound on support
392        vec low;
393//! upper bound on support
394        vec high;
395//! internal
396        vec distance;
397//! normalizing coefficients
398        double nk;
399//! cache of log( \c nk )
400        double lnk;
401public:
402        //! \name Constructors
403        //!@{
404        euni ( ) :epdf ( ) {}
405        euni ( const vec &low0, const vec &high0 ) {set_parameters ( low0,high0 );}
406        void set_parameters ( const vec &low0, const vec &high0 ) {
407                distance = high0-low0;
408                it_assert_debug ( min ( distance ) >0.0,"bad support" );
409                low = low0;
410                high = high0;
411                nk = prod ( 1.0/distance );
412                lnk = log ( nk );
413                dim = low.length();
414        }
415        //!@}
416
417        double eval ( const vec &val ) const  {return nk;}
418        double evallog ( const vec &val ) const  {return lnk;}
419        vec sample() const {
420                vec smp ( dim );
421#pragma omp critical
422                UniRNG.sample_vector ( dim ,smp );
423                return low+elem_mult ( distance,smp );
424        }
425        //! set values of \c low and \c high
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        //! \name Constructors
446        //!@{
447        mlnorm ( ) :mEF (),epdf ( ),A ( ),_mu ( epdf._mu() ) {ep =&epdf; };
448        mlnorm ( const  mat &A, const vec &mu0, const sq_T &R ) :epdf ( ),_mu ( epdf._mu() ) {
449                ep =&epdf; set_parameters ( A,mu0,R );
450        };
451        //! Set \c A and \c R
452        void set_parameters ( const  mat &A, const vec &mu0, const sq_T &R );
453        //!@}
454        //! Set value of \c rvc . Result of this operation is stored in \c epdf use function \c _ep to access it.
455        void condition ( const vec &cond );
456
457        //!access function
458        vec& _mu_const() {return mu_const;}
459        //!access function
460        mat& _A() {return A;}
461        //!access function
462        mat _R() {return epdf._R().to_mat();}
463
464        template<class sq_M>
465        friend std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_M> &ml );
466};
467
468//! Mpdf with general function for mean value
469template<class sq_T>
470class mgnorm : public mEF {
471protected:
472        //! Internal epdf that arise by conditioning on \c rvc
473        enorm<sq_T> epdf;
474        vec &mu;
475        fnc* g;
476public:
477        //!default constructor
478        mgnorm() :mu ( epdf._mu() ) {ep=&epdf;}
479        //!set mean function
480        void set_parameters ( fnc* g0, const sq_T &R0 ) {g=g0; epdf.set_parameters ( zeros ( g->dimension() ), R0 );}
481        void condition ( const vec &cond ) {mu=g->eval ( cond );};
482};
483
484/*! (Approximate) Student t density with linear function of mean value
485
486The internal epdf of this class is of the type of a Gaussian (enorm).
487However, each conditioning is trying to assure the best possible approximation by taking into account the zeta function. See [] for reference.
488
489Perhaps a moment-matching technique?
490*/
491class mlstudent : public mlnorm<ldmat> {
492protected:
493        ldmat Lambda;
494        ldmat &_R;
495        ldmat Re;
496public:
497        mlstudent ( ) :mlnorm<ldmat> (),
498                        Lambda (),      _R ( epdf._R() ) {}
499        void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0 ) {
500                it_assert_debug ( A0.rows() ==mu0.length(),"" );
501                it_assert_debug ( R0.rows() ==A0.rows(),"" );
502
503                epdf.set_parameters ( mu0,Lambda ); //
504                A = A0;
505                mu_const = mu0;
506                Re=R0;
507                Lambda = Lambda0;
508        }
509        void condition ( const vec &cond ) {
510                _mu = A*cond + mu_const;
511                double zeta;
512                //ugly hack!
513                if ( ( cond.length() +1 ) ==Lambda.rows() ) {
514                        zeta = Lambda.invqform ( concat ( cond, vec_1 ( 1.0 ) ) );
515                }
516                else {
517                        zeta = Lambda.invqform ( cond );
518                }
519                _R = Re;
520                _R*= ( 1+zeta );// / ( nu ); << nu is in Re!!!!!!
521        };
522
523};
524/*!
525\brief  Gamma random walk
526
527Mean value, \f$\mu\f$, of this density is given by \c rvc .
528Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
529This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
530
531The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
532*/
533class mgamma : public mEF {
534protected:
535        //! Internal epdf that arise by conditioning on \c rvc
536        egamma epdf;
537        //! Constant \f$k\f$
538        double k;
539        //! cache of epdf.beta
540        vec &_beta;
541
542public:
543        //! Constructor
544        mgamma ( ) : mEF ( ), epdf (), _beta ( epdf._beta() ) {ep=&epdf;};
545        //! Set value of \c k
546        void set_parameters ( double k, const vec &beta0 );
547        void condition ( const vec &val ) {_beta=k/val;};
548};
549
550/*!
551\brief  Inverse-Gamma random walk
552
553Mean value, \f$ \mu \f$, of this density is given by \c rvc .
554Standard deviation of the random walk is proportional to one \f$ k \f$-th the mean.
555This is achieved by setting \f$ \alpha=\mu/k^2+2 \f$ and \f$ \beta=\mu(\alpha-1)\f$.
556
557The standard deviation of the walk is then: \f$ \mu/\sqrt(k)\f$.
558 */
559class migamma : public mEF {
560protected:
561        //! Internal epdf that arise by conditioning on \c rvc
562        eigamma epdf;
563        //! Constant \f$k\f$
564        double k;
565        //! cache of epdf.alpha
566        vec &_alpha;
567        //! cache of epdf.beta
568        vec &_beta;
569
570public:
571        //! \name Constructors
572        //!@{
573        migamma ( ) : mEF (), epdf ( ), _alpha ( epdf._alpha() ), _beta ( epdf._beta() ) {ep=&epdf;};
574        migamma ( const migamma &m ) : mEF (), epdf ( m.epdf ), _alpha ( epdf._alpha() ), _beta ( epdf._beta() ) {ep=&epdf;};
575        //!@}
576
577        //! Set value of \c k
578        void set_parameters ( int len, double k0 ) {
579                k=k0;
580                epdf.set_parameters ( ( 1.0/ ( k*k ) +2.0 ) *ones ( len ) /*alpha*/, ones ( len ) /*beta*/ );
581                dimc = dimension();
582        };
583        void condition ( const vec &val ) {
584                _beta=elem_mult ( val, ( _alpha-1.0 ) );
585        };
586};
587
588/*!
589\brief  Gamma random walk around a fixed point
590
591Mean 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
592\f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
593
594Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
595This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
596
597The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
598*/
599class mgamma_fix : public mgamma {
600protected:
601        //! parameter l
602        double l;
603        //! reference vector
604        vec refl;
605public:
606        //! Constructor
607        mgamma_fix ( ) : mgamma ( ),refl () {};
608        //! Set value of \c k
609        void set_parameters ( double k0 , vec ref0, double l0 ) {
610                mgamma::set_parameters ( k0, ref0 );
611                refl=pow ( ref0,1.0-l0 );l=l0;
612                dimc=dimension();
613        };
614
615        void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); _beta=k/mean;};
616};
617
618
619/*!
620\brief  Inverse-Gamma random walk around a fixed point
621
622Mean 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
623\f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
624
625==== Check == vv =
626Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
627This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
628
629The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
630 */
631class migamma_ref : public migamma {
632protected:
633        //! parameter l
634        double l;
635        //! reference vector
636        vec refl;
637public:
638        //! Constructor
639        migamma_ref ( ) : migamma (),refl ( ) {};
640        //! Set value of \c k
641        void set_parameters ( double k0 , vec ref0, double l0 ) {
642                migamma::set_parameters ( ref0.length(), k0 );
643                refl=pow ( ref0,1.0-l0 );
644                l=l0;
645                dimc = dimension();
646        };
647
648        void condition ( const vec &val ) {
649                vec mean=elem_mult ( refl,pow ( val,l ) );
650                migamma::condition ( mean );
651        };
652};
653
654/*! Log-Normal probability density
655 only allow diagonal covariances!
656
657Density of the form \f$ \log(x)\sim \mathcal{N}(\mu,\sigma^2), i.e.
658\f[
659x \sim \frac{1}{x\sigma\sqrt{2\pi}}\exp{-\frac{1}{2\sigma^2}(\log(x)-\mu)}
660\f]
661
662*/
663class elognorm: public enorm<ldmat>{
664        public:
665                vec sample() const {return exp(enorm<ldmat>::sample());};
666                vec mean() const {vec var=enorm<ldmat>::variance();return exp(mu - 0.5*var);};
667               
668};
669
670/*!
671\brief  Log-Normal random walk
672
673Mean value, \f$\mu\f$, is...
674
675==== Check == vv =
676Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
677This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
678
679The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
680 */
681class mlognorm : public mpdf {
682        protected:
683                elognorm eno;
684        //! parameter 1/2*sigma^2
685                double sig2;
686                //! access
687                vec &mu;
688        public:
689        //! Constructor
690                mlognorm ( ) : eno (), mu(eno._mu()) {ep=&eno;};
691        //! Set value of \c k
692                void set_parameters ( int size, double k) {
693                        sig2 = 0.5*log(k*k+1);
694                        eno.set_parameters(zeros(size),2*sig2*eye(size));
695                       
696                        dimc = size;
697                };
698
699                void condition ( const vec &val ) {
700                        mu=log(val)-sig2;//elem_mult ( refl,pow ( val,l ) );
701                };
702};
703
704/*! inverse Wishart density
705
706*/
707class iW : public epdf{
708        public:
709                vec sample(){}
710};
711
712//! Switch between various resampling methods.
713enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
714/*!
715\brief Weighted empirical density
716
717Used e.g. in particle filters.
718*/
719class eEmp: public epdf {
720protected :
721        //! Number of particles
722        int n;
723        //! Sample weights \f$w\f$
724        vec w;
725        //! Samples \f$x^{(i)}, i=1..n\f$
726        Array<vec> samples;
727public:
728        //! \name Constructors
729        //!@{
730        eEmp ( ) :epdf ( ),w ( ),samples ( ) {};
731        eEmp ( const eEmp &e ) : epdf ( e ), w ( e.w ), samples ( e.samples ) {};
732        //!@}
733
734        //! Set samples and weights
735        void set_statistics ( const vec &w0, const epdf* pdf0 );
736        //! Set samples and weights
737        void set_statistics ( const epdf* pdf0 , int n ) {set_statistics ( ones ( n ) /n,pdf0 );};
738        //! Set sample
739        void set_samples ( const epdf* pdf0 );
740        //! Set sample
741        void set_parameters ( int n0, bool copy=true ) {n=n0; w.set_size ( n0,copy );samples.set_size ( n0,copy );};
742        //! Potentially dangerous, use with care.
743        vec& _w()  {return w;};
744        //! Potentially dangerous, use with care.
745        const vec& _w() const {return w;};
746        //! access function
747        Array<vec>& _samples() {return samples;};
748        //! access function
749        const Array<vec>& _samples() const {return samples;};
750        //! 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.
751        ivec resample ( RESAMPLING_METHOD method=SYSTEMATIC );
752        //! inherited operation : NOT implemneted
753        vec sample() const {it_error ( "Not implemented" );return 0;}
754        //! inherited operation : NOT implemneted
755        double evallog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
756        vec mean() const {
757                vec pom=zeros ( dim );
758                for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
759                return pom;
760        }
761        vec variance() const {
762                vec pom=zeros ( dim );
763                for ( int i=0;i<n;i++ ) {pom+=pow ( samples ( i ),2 ) *w ( i );}
764                return pom-pow ( mean(),2 );
765        }
766        //! For this class, qbounds are minimum and maximum value of the population!
767        void qbounds ( vec &lb, vec &ub, double perc=0.95 ) const {
768                // lb in inf so than it will be pushed below;
769                lb.set_size(dim);
770                ub.set_size(dim);
771                lb = std::numeric_limits<double>::infinity();
772                ub = -std::numeric_limits<double>::infinity();
773                int j;
774                for ( int i=0;i<n;i++ ) {
775                        for ( j=0;j<dim; j++ ) {
776                                if ( samples ( i ) ( j ) <lb ( j ) ) {lb ( j ) =samples ( i ) ( j );}
777                                if ( samples ( i ) ( j ) >ub ( j ) ) {ub ( j ) =samples ( i ) ( j );}
778                        }
779                }
780        }
781};
782
783
784////////////////////////
785
786template<class sq_T>
787void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
788//Fixme test dimensions of mu0 and R0;
789        mu = mu0;
790        R = R0;
791        dim = mu0.length();
792};
793
794template<class sq_T>
795void enorm<sq_T>::dupdate ( mat &v, double nu ) {
796        //
797};
798
799// template<class sq_T>
800// void enorm<sq_T>::tupdate ( double phi, mat &vbar, double nubar ) {
801//      //
802// };
803
804template<class sq_T>
805vec enorm<sq_T>::sample() const {
806        vec x ( dim );
807#pragma omp critical
808        NorRNG.sample_vector ( dim,x );
809        vec smp = R.sqrt_mult ( x );
810
811        smp += mu;
812        return smp;
813};
814
815template<class sq_T>
816mat enorm<sq_T>::sample ( int N ) const {
817        mat X ( dim,N );
818        vec x ( dim );
819        vec pom;
820        int i;
821
822        for ( i=0;i<N;i++ ) {
823#pragma omp critical
824                NorRNG.sample_vector ( dim,x );
825                pom = R.sqrt_mult ( x );
826                pom +=mu;
827                X.set_col ( i, pom );
828        }
829
830        return X;
831};
832
833// template<class sq_T>
834// double enorm<sq_T>::eval ( const vec &val ) const {
835//      double pdfl,e;
836//      pdfl = evallog ( val );
837//      e = exp ( pdfl );
838//      return e;
839// };
840
841template<class sq_T>
842double enorm<sq_T>::evallog_nn ( const vec &val ) const {
843        // 1.83787706640935 = log(2pi)
844        double tmp=-0.5* ( R.invqform ( mu-val ) );// - lognc();
845        return  tmp;
846};
847
848template<class sq_T>
849inline double enorm<sq_T>::lognc () const {
850        // 1.83787706640935 = log(2pi)
851        double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
852        return tmp;
853};
854
855template<class sq_T>
856void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 ) {
857        it_assert_debug ( A0.rows() ==mu0.length(),"" );
858        it_assert_debug ( A0.rows() ==R0.rows(),"" );
859
860        epdf.set_parameters ( zeros ( A0.rows() ),R0 );
861        A = A0;
862        mu_const = mu0;
863        dimc=A0.cols();
864}
865
866// template<class sq_T>
867// vec mlnorm<sq_T>::samplecond (const  vec &cond, double &lik ) {
868//      this->condition ( cond );
869//      vec smp = epdf.sample();
870//      lik = epdf.eval ( smp );
871//      return smp;
872// }
873
874// template<class sq_T>
875// mat mlnorm<sq_T>::samplecond (const vec &cond, vec &lik, int n ) {
876//      int i;
877//      int dim = rv.count();
878//      mat Smp ( dim,n );
879//      vec smp ( dim );
880//      this->condition ( cond );
881//
882//      for ( i=0; i<n; i++ ) {
883//              smp = epdf.sample();
884//              lik ( i ) = epdf.eval ( smp );
885//              Smp.set_col ( i ,smp );
886//      }
887//
888//      return Smp;
889// }
890
891template<class sq_T>
892void mlnorm<sq_T>::condition ( const vec &cond ) {
893        _mu = A*cond + mu_const;
894//R is already assigned;
895}
896
897template<class sq_T>
898epdf* enorm<sq_T>::marginal ( const RV &rvn ) const {
899        it_assert_debug ( isnamed(), "rv description is not assigned" );
900        ivec irvn = rvn.dataind ( rv );
901
902        sq_T Rn ( R,irvn ); //select rows and columns of R
903
904        enorm<sq_T>* tmp = new enorm<sq_T>;
905        tmp->set_rv ( rvn );
906        tmp->set_parameters ( mu ( irvn ), Rn );
907        return tmp;
908}
909
910template<class sq_T>
911mpdf* enorm<sq_T>::condition ( const RV &rvn ) const {
912
913        it_assert_debug ( isnamed(),"rvs are not assigned" );
914
915        RV rvc = rv.subt ( rvn );
916        it_assert_debug ( ( rvc._dsize() +rvn._dsize() ==rv._dsize() ),"wrong rvn" );
917        //Permutation vector of the new R
918        ivec irvn = rvn.dataind ( rv );
919        ivec irvc = rvc.dataind ( rv );
920        ivec perm=concat ( irvn , irvc );
921        sq_T Rn ( R,perm );
922
923        //fixme - could this be done in general for all sq_T?
924        mat S=Rn.to_mat();
925        //fixme
926        int n=rvn._dsize()-1;
927        int end=R.rows()-1;
928        mat S11 = S.get ( 0,n, 0, n );
929        mat S12 = S.get ( 0, n , rvn._dsize(), end );
930        mat S22 = S.get ( rvn._dsize(), end, rvn._dsize(), end );
931
932        vec mu1 = mu ( irvn );
933        vec mu2 = mu ( irvc );
934        mat A=S12*inv ( S22 );
935        sq_T R_n ( S11 - A *S12.T() );
936
937        mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( );
938        tmp->set_rv ( rvn ); tmp->set_rvc ( rvc );
939        tmp->set_parameters ( A,mu1-A*mu2,R_n );
940        return tmp;
941}
942
943///////////
944
945template<class sq_T>
946std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_T> &ml ) {
947        os << "A:"<< ml.A<<endl;
948        os << "mu:"<< ml.mu_const<<endl;
949        os << "R:" << ml.epdf._R().to_mat() <<endl;
950        return os;
951};
952
953}
954#endif //EF_H
Note: See TracBrowser for help on using the browser.