00001
00013 #ifndef EF_H
00014 #define EF_H
00015
00016
00017 #include "libBM.h"
00018 #include "../math/chmat.h"
00019
00020
00021 namespace bdm
00022 {
00023
00024
00026 extern Uniform_RNG UniRNG;
00028 extern Normal_RNG NorRNG;
00030 extern Gamma_RNG GamRNG;
00031
00038 class eEF : public epdf
00039 {
00040 public:
00041
00043 eEF ( ) :epdf ( ) {};
00045 virtual double lognc() const =0;
00047 virtual void dupdate ( mat &v ) {it_error ( "Not implemented" );};
00049 virtual double evallog_nn ( const vec &val ) const{it_error ( "Not implemented" );return 0.0;};
00051 virtual double evallog ( const vec &val ) const {double tmp;tmp= evallog_nn ( val )-lognc();it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); return tmp;}
00053 virtual vec evallog ( const mat &Val ) const
00054 {
00055 vec x ( Val.cols() );
00056 for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evallog_nn ( Val.get_col ( i ) ) ;}
00057 return x-lognc();
00058 }
00060 virtual void pow ( double p ) {it_error ( "Not implemented" );};
00061 };
00062
00069 class mEF : public mpdf
00070 {
00071
00072 public:
00074 mEF ( ) :mpdf ( ) {};
00075 };
00076
00078 class BMEF : public BM
00079 {
00080 protected:
00082 double frg;
00084 double last_lognc;
00085 public:
00087 BMEF ( double frg0=1.0 ) :BM ( ), frg ( frg0 ) {}
00089 BMEF ( const BMEF &B ) :BM ( B ), frg ( B.frg ), last_lognc ( B.last_lognc ) {}
00091 virtual void set_statistics ( const BMEF* BM0 ) {it_error ( "Not implemented" );};
00093 virtual void bayes ( const vec &data, const double w ) {};
00094
00095 void bayes ( const vec &dt );
00097 virtual void flatten ( const BMEF * B ) {it_error ( "Not implemented" );}
00099
00100
00101 BMEF* _copy_ () const {it_error ( "function _copy_ not implemented for this BM" ); return NULL;};
00102 };
00103
00104 template<class sq_T>
00105 class mlnorm;
00106
00112 template<class sq_T>
00113 class enorm : public eEF
00114 {
00115 protected:
00117 vec mu;
00119 sq_T R;
00120 public:
00123
00124 enorm ( ) :eEF ( ), mu ( ),R ( ) {};
00125 enorm ( const vec &mu,const sq_T &R ) {set_parameters ( mu,R );}
00126 void set_parameters ( const vec &mu,const sq_T &R );
00128
00131
00133 void dupdate ( mat &v,double nu=1.0 );
00134
00135 vec sample() const;
00136 mat sample ( int N ) const;
00137 double evallog_nn ( const vec &val ) const;
00138 double lognc () const;
00139 vec mean() const {return mu;}
00140 vec variance() const {return diag ( R.to_mat() );}
00141
00142 mpdf* condition ( const RV &rvn ) const ;
00143 enorm<sq_T>* marginal ( const RV &rv ) const;
00144
00146
00149
00150 vec& _mu() {return mu;}
00151 void set_mu ( const vec mu0 ) { mu=mu0;}
00152 sq_T& _R() {return R;}
00153 const sq_T& _R() const {return R;}
00155
00156 };
00157
00164 class egiw : public eEF
00165 {
00166 protected:
00168 ldmat V;
00170 double nu;
00172 int dimx;
00174 int nPsi;
00175 public:
00178 egiw() :eEF() {};
00179 egiw ( int dimx0, ldmat V0, double nu0=-1.0 ) :eEF() {set_parameters ( dimx0,V0, nu0 );};
00180
00181 void set_parameters ( int dimx0, ldmat V0, double nu0=-1.0 )
00182 {
00183 dimx=dimx0;
00184 nPsi = V0.rows()-dimx;
00185 dim = dimx* ( dimx+nPsi );
00186
00187 V=V0;
00188 if ( nu0<0 )
00189 {
00190 nu = 0.1 +nPsi +2*dimx +2;
00191
00192 }
00193 else
00194 {
00195 nu=nu0;
00196 }
00197 }
00199
00200 vec sample() const;
00201 vec mean() const;
00202 vec variance() const;
00203 void mean_mat ( mat &M, mat&R ) const;
00205 double evallog_nn ( const vec &val ) const;
00206 double lognc () const;
00207 void pow ( double p ) {V*=p;nu*=p;};
00208
00211
00212 ldmat& _V() {return V;}
00213 const ldmat& _V() const {return V;}
00214 double& _nu() {return nu;}
00215 const double& _nu() const {return nu;}
00217 };
00218
00227 class eDirich: public eEF
00228 {
00229 protected:
00231 vec beta;
00232 public:
00235
00236 eDirich () : eEF ( ) {};
00237 eDirich ( const eDirich &D0 ) : eEF () {set_parameters ( D0.beta );};
00238 eDirich ( const vec &beta0 ) {set_parameters ( beta0 );};
00239 void set_parameters ( const vec &beta0 )
00240 {
00241 beta= beta0;
00242 dim = beta.length();
00243 }
00245
00246 vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
00247 vec mean() const {return beta/sum(beta);};
00248 vec variance() const {double gamma =sum(beta); return elem_mult ( beta, ( beta+1 ) ) / ( gamma* ( gamma+1 ) );}
00250 double evallog_nn ( const vec &val ) const
00251 {
00252 double tmp; tmp= ( beta-1 ) *log ( val ); it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
00253 return tmp;
00254 };
00255 double lognc () const
00256 {
00257 double tmp;
00258 double gam=sum ( beta );
00259 double lgb=0.0;
00260 for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
00261 tmp= lgb-lgamma ( gam );
00262 it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
00263 return tmp;
00264 };
00266 vec& _beta() {return beta;}
00268 };
00269
00271 class multiBM : public BMEF
00272 {
00273 protected:
00275 eDirich est;
00277 vec β
00278 public:
00280 multiBM ( ) : BMEF ( ),est ( ),beta ( est._beta() )
00281 {
00282 if ( beta.length() >0 ) {last_lognc=est.lognc();}
00283 else{last_lognc=0.0;}
00284 }
00286 multiBM ( const multiBM &B ) : BMEF ( B ),est ( B.est ),beta ( est._beta() ) {}
00288 void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
00289 void bayes ( const vec &dt )
00290 {
00291 if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
00292 beta+=dt;
00293 if ( evalll ) {ll=est.lognc()-last_lognc;}
00294 }
00295 double logpred ( const vec &dt ) const
00296 {
00297 eDirich pred ( est );
00298 vec &beta = pred._beta();
00299
00300 double lll;
00301 if ( frg<1.0 )
00302 {beta*=frg;lll=pred.lognc();}
00303 else
00304 if ( evalll ) {lll=last_lognc;}
00305 else{lll=pred.lognc();}
00306
00307 beta+=dt;
00308 return pred.lognc()-lll;
00309 }
00310 void flatten ( const BMEF* B )
00311 {
00312 const multiBM* E=dynamic_cast<const multiBM*> ( B );
00313
00314 const vec &Eb=E->beta;
00315 beta*= ( sum ( Eb ) /sum ( beta ) );
00316 if ( evalll ) {last_lognc=est.lognc();}
00317 }
00318 const epdf& posterior() const {return est;};
00319 const eDirich* _e() const {return &est;};
00320 void set_parameters ( const vec &beta0 )
00321 {
00322 est.set_parameters ( beta0 );
00323 if ( evalll ) {last_lognc=est.lognc();}
00324 }
00325 };
00326
00336 class egamma : public eEF
00337 {
00338 protected:
00340 vec alpha;
00342 vec beta;
00343 public :
00346 egamma ( ) :eEF ( ), alpha ( 0 ), beta ( 0 ) {};
00347 egamma ( const vec &a, const vec &b ) {set_parameters ( a, b );};
00348 void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;dim = alpha.length();};
00350
00351 vec sample() const;
00353
00354 double evallog ( const vec &val ) const;
00355 double lognc () const;
00357 vec& _alpha() {return alpha;}
00358 vec& _beta() {return beta;}
00359 vec mean() const {return elem_div ( alpha,beta );}
00360 vec variance() const {return elem_div ( alpha,elem_mult ( beta,beta ) ); }
00361 };
00362
00379 class eigamma : public egamma
00380 {
00381 protected:
00382 public :
00387
00388 vec sample() const {return 1.0/egamma::sample();};
00390 vec mean() const {return elem_div ( beta,alpha-1 );}
00391 vec variance() const {vec mea=mean(); return elem_div ( elem_mult ( mea,mea ),alpha-2 );}
00392 };
00393
00395
00396
00397
00398
00399
00400
00402
00403
00404
00405
00406
00407
00408
00410
00411 class euni: public epdf
00412 {
00413 protected:
00415 vec low;
00417 vec high;
00419 vec distance;
00421 double nk;
00423 double lnk;
00424 public:
00427 euni ( ) :epdf ( ) {}
00428 euni ( const vec &low0, const vec &high0 ) {set_parameters ( low0,high0 );}
00429 void set_parameters ( const vec &low0, const vec &high0 )
00430 {
00431 distance = high0-low0;
00432 it_assert_debug ( min ( distance ) >0.0,"bad support" );
00433 low = low0;
00434 high = high0;
00435 nk = prod ( 1.0/distance );
00436 lnk = log ( nk );
00437 dim = low.length();
00438 }
00440
00441 double eval ( const vec &val ) const {return nk;}
00442 double evallog ( const vec &val ) const {return lnk;}
00443 vec sample() const
00444 {
00445 vec smp ( dim );
00446 #pragma omp critical
00447 UniRNG.sample_vector ( dim ,smp );
00448 return low+elem_mult ( distance,smp );
00449 }
00451 vec mean() const {return ( high-low ) /2.0;}
00452 vec variance() const {return ( pow ( high,2 ) +pow ( low,2 ) +elem_mult ( high,low ) ) /3.0;}
00453 };
00454
00455
00461 template<class sq_T>
00462 class mlnorm : public mEF
00463 {
00464 protected:
00466 enorm<sq_T> epdf;
00467 mat A;
00468 vec mu_const;
00469 vec& _mu;
00470 public:
00473 mlnorm ( ) :mEF (),epdf ( ),A ( ),_mu ( epdf._mu() ) {ep =&epdf; };
00474 mlnorm ( const mat &A, const vec &mu0, const sq_T &R ) :epdf ( ),_mu ( epdf._mu() )
00475 {
00476 ep =&epdf; set_parameters ( A,mu0,R );
00477 };
00479 void set_parameters ( const mat &A, const vec &mu0, const sq_T &R );
00482 void condition ( const vec &cond );
00483
00485 vec& _mu_const() {return mu_const;}
00487 mat& _A() {return A;}
00489 mat _R() {return epdf._R().to_mat();}
00490
00491 template<class sq_M>
00492 friend std::ostream &operator<< ( std::ostream &os, mlnorm<sq_M> &ml );
00493 };
00494
00496 template<class sq_T>
00497 class mgnorm : public mEF
00498 {
00499 protected:
00501 enorm<sq_T> epdf;
00502 vec μ
00503 fnc* g;
00504 public:
00506 mgnorm() :mu ( epdf._mu() ) {ep=&epdf;}
00508 void set_parameters ( fnc* g0, const sq_T &R0 ) {g=g0; epdf.set_parameters ( zeros ( g->dimension() ), R0 );}
00509 void condition ( const vec &cond ) {mu=g->eval ( cond );};
00510 };
00511
00519 class mlstudent : public mlnorm<ldmat>
00520 {
00521 protected:
00522 ldmat Lambda;
00523 ldmat &_R;
00524 ldmat Re;
00525 public:
00526 mlstudent ( ) :mlnorm<ldmat> (),
00527 Lambda (), _R ( epdf._R() ) {}
00528 void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0 )
00529 {
00530 it_assert_debug ( A0.rows() ==mu0.length(),"" );
00531 it_assert_debug ( R0.rows() ==A0.rows(),"" );
00532
00533 epdf.set_parameters ( mu0,Lambda );
00534 A = A0;
00535 mu_const = mu0;
00536 Re=R0;
00537 Lambda = Lambda0;
00538 }
00539 void condition ( const vec &cond )
00540 {
00541 _mu = A*cond + mu_const;
00542 double zeta;
00543
00544 if ( ( cond.length() +1 ) ==Lambda.rows() )
00545 {
00546 zeta = Lambda.invqform ( concat ( cond, vec_1 ( 1.0 ) ) );
00547 }
00548 else
00549 {
00550 zeta = Lambda.invqform ( cond );
00551 }
00552 _R = Re;
00553 _R*= ( 1+zeta );
00554 };
00555
00556 };
00566 class mgamma : public mEF
00567 {
00568 protected:
00570 egamma epdf;
00572 double k;
00574 vec &_beta;
00575
00576 public:
00578 mgamma ( ) : mEF ( ), epdf (), _beta ( epdf._beta() ) {ep=&epdf;};
00580 void set_parameters ( double k, const vec &beta0 );
00581 void condition ( const vec &val ) {_beta=k/val;};
00582 };
00583
00593 class migamma : public mEF
00594 {
00595 protected:
00597 eigamma epdf;
00599 double k;
00601 vec &_alpha;
00603 vec &_beta;
00604
00605 public:
00608 migamma ( ) : mEF (), epdf ( ), _alpha ( epdf._alpha() ), _beta ( epdf._beta() ) {ep=&epdf;};
00609 migamma ( const migamma &m ) : mEF (), epdf ( m.epdf ), _alpha ( epdf._alpha() ), _beta ( epdf._beta() ) {ep=&epdf;};
00611
00613 void set_parameters ( int len, double k0 )
00614 {
00615 k=k0;
00616 epdf.set_parameters ( ( 1.0/ ( k*k ) +2.0 ) *ones ( len ) , ones ( len ) );
00617 dimc = dimension();
00618 };
00619 void condition ( const vec &val )
00620 {
00621 _beta=elem_mult ( val, ( _alpha-1.0 ) );
00622 };
00623 };
00624
00636 class mgamma_fix : public mgamma
00637 {
00638 protected:
00640 double l;
00642 vec refl;
00643 public:
00645 mgamma_fix ( ) : mgamma ( ),refl () {};
00647 void set_parameters ( double k0 , vec ref0, double l0 )
00648 {
00649 mgamma::set_parameters ( k0, ref0 );
00650 refl=pow ( ref0,1.0-l0 );l=l0;
00651 dimc=dimension();
00652 };
00653
00654 void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); _beta=k/mean;};
00655 };
00656
00657
00670 class migamma_ref : public migamma
00671 {
00672 protected:
00674 double l;
00676 vec refl;
00677 public:
00679 migamma_ref ( ) : migamma (),refl ( ) {};
00681 void set_parameters ( double k0 , vec ref0, double l0 )
00682 {
00683 migamma::set_parameters ( ref0.length(), k0 );
00684 refl=pow ( ref0,1.0-l0 );
00685 l=l0;
00686 dimc = dimension();
00687 };
00688
00689 void condition ( const vec &val )
00690 {
00691 vec mean=elem_mult ( refl,pow ( val,l ) );
00692 migamma::condition ( mean );
00693 };
00694 };
00695
00705 class elognorm: public enorm<ldmat>
00706 {
00707 public:
00708 vec sample() const {return exp ( enorm<ldmat>::sample() );};
00709 vec mean() const {vec var=enorm<ldmat>::variance();return exp ( mu - 0.5*var );};
00710
00711 };
00712
00724 class mlognorm : public mpdf
00725 {
00726 protected:
00727 elognorm eno;
00729 double sig2;
00731 vec μ
00732 public:
00734 mlognorm ( ) : eno (), mu ( eno._mu() ) {ep=&eno;};
00736 void set_parameters ( int size, double k )
00737 {
00738 sig2 = 0.5*log ( k*k+1 );
00739 eno.set_parameters ( zeros ( size ),2*sig2*eye ( size ) );
00740
00741 dimc = size;
00742 };
00743
00744 void condition ( const vec &val )
00745 {
00746 mu=log ( val )-sig2;
00747 };
00748 };
00749
00753 class eWishartCh : public epdf
00754 {
00755 protected:
00757 chmat Y;
00759 int p;
00761 double delta;
00762 public:
00763 void set_parameters ( const mat &Y0, const double delta0 ) {Y=chmat ( Y0 );delta=delta0; p=Y.rows(); dim = p*p; }
00764 mat sample_mat() const
00765 {
00766 mat X=zeros ( p,p );
00767
00768
00769 for ( int i=0;i<p;i++ )
00770 {
00771 GamRNG.setup ( 0.5* ( delta-i ) , 0.5 );
00772 #pragma omp critical
00773 X ( i,i ) =sqrt ( GamRNG() );
00774 }
00775
00776 for ( int i=0;i<p;i++ )
00777 {
00778 for ( int j=i+1;j<p;j++ )
00779 {
00780 #pragma omp critical
00781 X ( i,j ) =NorRNG.sample();
00782 }
00783 }
00784 return X*Y._Ch();
00785 }
00786 vec sample () const
00787 {
00788 return vec ( sample_mat()._data(),p*p );
00789 }
00791 void setY ( const mat &Ch0 ) {copy_vector ( dim,Ch0._data(), Y._Ch()._data() );}
00793 void _setY ( const vec &ch0 ) {copy_vector ( dim, ch0._data(), Y._Ch()._data() ); }
00795 const chmat& getY()const {return Y;}
00796 };
00797
00798 class eiWishartCh: public epdf
00799 {
00800 protected:
00801 eWishartCh W;
00802 int p;
00803 double delta;
00804 public:
00805 void set_parameters ( const mat &Y0, const double delta0) {
00806 delta = delta0;
00807 W.set_parameters ( inv ( Y0 ),delta0 );
00808 dim = W.dimension(); p=Y0.rows();
00809 }
00810 vec sample() const {mat iCh; iCh=inv ( W.sample_mat() ); return vec ( iCh._data(),dim );}
00811 void _setY ( const vec &y0 )
00812 {
00813 mat Ch ( p,p );
00814 mat iCh ( p,p );
00815 copy_vector ( dim, y0._data(), Ch._data() );
00816
00817 iCh=inv ( Ch );
00818 W.setY ( iCh );
00819 }
00820 virtual double evallog ( const vec &val ) const {
00821 chmat X(p);
00822 const chmat& Y=W.getY();
00823
00824 copy_vector(p*p,val._data(),X._Ch()._data());
00825 chmat iX(p);X.inv(iX);
00826
00827
00828 mat M=Y.to_mat()*iX.to_mat();
00829
00830 double log1 = 0.5*p*(2*Y.logdet())-0.5*(delta+p+1)*(2*X.logdet())-0.5*trace(M);
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 return log1;
00841 };
00842
00843 };
00844
00845 class rwiWishartCh : public mpdf
00846 {
00847 protected:
00848 eiWishartCh eiW;
00850 double sqd;
00851
00852 vec refl;
00853 double l;
00854 int p;
00855 public:
00856 void set_parameters ( int p0, double k, vec ref0, double l0 )
00857 {
00858 p=p0;
00859 double delta = 2/(k*k)+p+3;
00860 sqd=sqrt ( delta-p-1 );
00861 l=l0;
00862 refl=pow(ref0,1-l);
00863
00864 eiW.set_parameters ( eye ( p ),delta );
00865 ep=&eiW;
00866 dimc=eiW.dimension();
00867 }
00868 void condition ( const vec &c ) {
00869 vec z=c;
00870 int ri=0;
00871 for(int i=0;i<p*p;i+=(p+1)){
00872 z(i) = pow(z(i),l)*refl(ri);
00873 ri++;
00874 }
00875
00876 eiW._setY ( sqd*z );
00877 }
00878 };
00879
00881 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
00887 class eEmp: public epdf
00888 {
00889 protected :
00891 int n;
00893 vec w;
00895 Array<vec> samples;
00896 public:
00899 eEmp ( ) :epdf ( ),w ( ),samples ( ) {};
00900 eEmp ( const eEmp &e ) : epdf ( e ), w ( e.w ), samples ( e.samples ) {};
00902
00904 void set_statistics ( const vec &w0, const epdf* pdf0 );
00906 void set_statistics ( const epdf* pdf0 , int n ) {set_statistics ( ones ( n ) /n,pdf0 );};
00908 void set_samples ( const epdf* pdf0 );
00910 void set_parameters ( int n0, bool copy=true ) {n=n0; w.set_size ( n0,copy );samples.set_size ( n0,copy );};
00912 vec& _w() {return w;};
00914 const vec& _w() const {return w;};
00916 Array<vec>& _samples() {return samples;};
00918 const Array<vec>& _samples() const {return samples;};
00920 ivec resample ( RESAMPLING_METHOD method=SYSTEMATIC );
00922 vec sample() const {it_error ( "Not implemented" );return 0;}
00924 double evallog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
00925 vec mean() const
00926 {
00927 vec pom=zeros ( dim );
00928 for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
00929 return pom;
00930 }
00931 vec variance() const
00932 {
00933 vec pom=zeros ( dim );
00934 for ( int i=0;i<n;i++ ) {pom+=pow ( samples ( i ),2 ) *w ( i );}
00935 return pom-pow ( mean(),2 );
00936 }
00938 void qbounds ( vec &lb, vec &ub, double perc=0.95 ) const
00939 {
00940
00941 lb.set_size ( dim );
00942 ub.set_size ( dim );
00943 lb = std::numeric_limits<double>::infinity();
00944 ub = -std::numeric_limits<double>::infinity();
00945 int j;
00946 for ( int i=0;i<n;i++ )
00947 {
00948 for ( j=0;j<dim; j++ )
00949 {
00950 if ( samples ( i ) ( j ) <lb ( j ) ) {lb ( j ) =samples ( i ) ( j );}
00951 if ( samples ( i ) ( j ) >ub ( j ) ) {ub ( j ) =samples ( i ) ( j );}
00952 }
00953 }
00954 }
00955 };
00956
00957
00959
00960 template<class sq_T>
00961 void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 )
00962 {
00963
00964 mu = mu0;
00965 R = R0;
00966 dim = mu0.length();
00967 };
00968
00969 template<class sq_T>
00970 void enorm<sq_T>::dupdate ( mat &v, double nu )
00971 {
00972
00973 };
00974
00975
00976
00977
00978
00979
00980 template<class sq_T>
00981 vec enorm<sq_T>::sample() const
00982 {
00983 vec x ( dim );
00984 #pragma omp critical
00985 NorRNG.sample_vector ( dim,x );
00986 vec smp = R.sqrt_mult ( x );
00987
00988 smp += mu;
00989 return smp;
00990 };
00991
00992 template<class sq_T>
00993 mat enorm<sq_T>::sample ( int N ) const
00994 {
00995 mat X ( dim,N );
00996 vec x ( dim );
00997 vec pom;
00998 int i;
00999
01000 for ( i=0;i<N;i++ )
01001 {
01002 #pragma omp critical
01003 NorRNG.sample_vector ( dim,x );
01004 pom = R.sqrt_mult ( x );
01005 pom +=mu;
01006 X.set_col ( i, pom );
01007 }
01008
01009 return X;
01010 };
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 template<class sq_T>
01021 double enorm<sq_T>::evallog_nn ( const vec &val ) const
01022 {
01023
01024 double tmp=-0.5* ( R.invqform ( mu-val ) );
01025 return tmp;
01026 };
01027
01028 template<class sq_T>
01029 inline double enorm<sq_T>::lognc () const
01030 {
01031
01032 double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
01033 return tmp;
01034 };
01035
01036 template<class sq_T>
01037 void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 )
01038 {
01039 it_assert_debug ( A0.rows() ==mu0.length(),"" );
01040 it_assert_debug ( A0.rows() ==R0.rows(),"" );
01041
01042 epdf.set_parameters ( zeros ( A0.rows() ),R0 );
01043 A = A0;
01044 mu_const = mu0;
01045 dimc=A0.cols();
01046 }
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 template<class sq_T>
01074 void mlnorm<sq_T>::condition ( const vec &cond )
01075 {
01076 _mu = A*cond + mu_const;
01077
01078 }
01079
01080 template<class sq_T>
01081 enorm<sq_T>* enorm<sq_T>::marginal ( const RV &rvn ) const
01082 {
01083 it_assert_debug ( isnamed(), "rv description is not assigned" );
01084 ivec irvn = rvn.dataind ( rv );
01085
01086 sq_T Rn ( R,irvn );
01087
01088 enorm<sq_T>* tmp = new enorm<sq_T>;
01089 tmp->set_rv ( rvn );
01090 tmp->set_parameters ( mu ( irvn ), Rn );
01091 return tmp;
01092 }
01093
01094 template<class sq_T>
01095 mpdf* enorm<sq_T>::condition ( const RV &rvn ) const
01096 {
01097
01098 it_assert_debug ( isnamed(),"rvs are not assigned" );
01099
01100 RV rvc = rv.subt ( rvn );
01101 it_assert_debug ( ( rvc._dsize() +rvn._dsize() ==rv._dsize() ),"wrong rvn" );
01102
01103 ivec irvn = rvn.dataind ( rv );
01104 ivec irvc = rvc.dataind ( rv );
01105 ivec perm=concat ( irvn , irvc );
01106 sq_T Rn ( R,perm );
01107
01108
01109 mat S=Rn.to_mat();
01110
01111 int n=rvn._dsize()-1;
01112 int end=R.rows()-1;
01113 mat S11 = S.get ( 0,n, 0, n );
01114 mat S12 = S.get ( 0, n , rvn._dsize(), end );
01115 mat S22 = S.get ( rvn._dsize(), end, rvn._dsize(), end );
01116
01117 vec mu1 = mu ( irvn );
01118 vec mu2 = mu ( irvc );
01119 mat A=S12*inv ( S22 );
01120 sq_T R_n ( S11 - A *S12.T() );
01121
01122 mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( );
01123 tmp->set_rv ( rvn ); tmp->set_rvc ( rvc );
01124 tmp->set_parameters ( A,mu1-A*mu2,R_n );
01125 return tmp;
01126 }
01127
01129
01130 template<class sq_T>
01131 std::ostream &operator<< ( std::ostream &os, mlnorm<sq_T> &ml )
01132 {
01133 os << "A:"<< ml.A<<endl;
01134 os << "mu:"<< ml.mu_const<<endl;
01135 os << "R:" << ml.epdf._R().to_mat() <<endl;
01136 return os;
01137 };
01138
01139 }
01140 #endif //EF_H