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
00205 vec est_theta() const;
00206
00208 ldmat est_theta_cov() const;
00209
00210 void mean_mat ( mat &M, mat&R ) const;
00212 double evallog_nn ( const vec &val ) const;
00213 double lognc () const;
00214 void pow ( double p ) {V*=p;nu*=p;};
00215
00218
00219 ldmat& _V() {return V;}
00220 const ldmat& _V() const {return V;}
00221 double& _nu() {return nu;}
00222 const double& _nu() const {return nu;}
00224 };
00225
00234 class eDirich: public eEF
00235 {
00236 protected:
00238 vec beta;
00239 public:
00242
00243 eDirich () : eEF ( ) {};
00244 eDirich ( const eDirich &D0 ) : eEF () {set_parameters ( D0.beta );};
00245 eDirich ( const vec &beta0 ) {set_parameters ( beta0 );};
00246 void set_parameters ( const vec &beta0 )
00247 {
00248 beta= beta0;
00249 dim = beta.length();
00250 }
00252
00253 vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
00254 vec mean() const {return beta/sum(beta);};
00255 vec variance() const {double gamma =sum(beta); return elem_mult ( beta, ( beta+1 ) ) / ( gamma* ( gamma+1 ) );}
00257 double evallog_nn ( const vec &val ) const
00258 {
00259 double tmp; tmp= ( beta-1 ) *log ( val ); it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
00260 return tmp;
00261 };
00262 double lognc () const
00263 {
00264 double tmp;
00265 double gam=sum ( beta );
00266 double lgb=0.0;
00267 for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
00268 tmp= lgb-lgamma ( gam );
00269 it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
00270 return tmp;
00271 };
00273 vec& _beta() {return beta;}
00275 };
00276
00278 class multiBM : public BMEF
00279 {
00280 protected:
00282 eDirich est;
00284 vec β
00285 public:
00287 multiBM ( ) : BMEF ( ),est ( ),beta ( est._beta() )
00288 {
00289 if ( beta.length() >0 ) {last_lognc=est.lognc();}
00290 else{last_lognc=0.0;}
00291 }
00293 multiBM ( const multiBM &B ) : BMEF ( B ),est ( B.est ),beta ( est._beta() ) {}
00295 void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
00296 void bayes ( const vec &dt )
00297 {
00298 if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
00299 beta+=dt;
00300 if ( evalll ) {ll=est.lognc()-last_lognc;}
00301 }
00302 double logpred ( const vec &dt ) const
00303 {
00304 eDirich pred ( est );
00305 vec &beta = pred._beta();
00306
00307 double lll;
00308 if ( frg<1.0 )
00309 {beta*=frg;lll=pred.lognc();}
00310 else
00311 if ( evalll ) {lll=last_lognc;}
00312 else{lll=pred.lognc();}
00313
00314 beta+=dt;
00315 return pred.lognc()-lll;
00316 }
00317 void flatten ( const BMEF* B )
00318 {
00319 const multiBM* E=dynamic_cast<const multiBM*> ( B );
00320
00321 const vec &Eb=E->beta;
00322 beta*= ( sum ( Eb ) /sum ( beta ) );
00323 if ( evalll ) {last_lognc=est.lognc();}
00324 }
00325 const epdf& posterior() const {return est;};
00326 const eDirich* _e() const {return &est;};
00327 void set_parameters ( const vec &beta0 )
00328 {
00329 est.set_parameters ( beta0 );
00330 if ( evalll ) {last_lognc=est.lognc();}
00331 }
00332 };
00333
00343 class egamma : public eEF
00344 {
00345 protected:
00347 vec alpha;
00349 vec beta;
00350 public :
00353 egamma ( ) :eEF ( ), alpha ( 0 ), beta ( 0 ) {};
00354 egamma ( const vec &a, const vec &b ) {set_parameters ( a, b );};
00355 void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;dim = alpha.length();};
00357
00358 vec sample() const;
00360
00361 double evallog ( const vec &val ) const;
00362 double lognc () const;
00364 vec& _alpha() {return alpha;}
00365 vec& _beta() {return beta;}
00366 vec mean() const {return elem_div ( alpha,beta );}
00367 vec variance() const {return elem_div ( alpha,elem_mult ( beta,beta ) ); }
00368 };
00369
00386 class eigamma : public egamma
00387 {
00388 protected:
00389 public :
00394
00395 vec sample() const {return 1.0/egamma::sample();};
00397 vec mean() const {return elem_div ( beta,alpha-1 );}
00398 vec variance() const {vec mea=mean(); return elem_div ( elem_mult ( mea,mea ),alpha-2 );}
00399 };
00400
00402
00403
00404
00405
00406
00407
00409
00410
00411
00412
00413
00414
00415
00417
00418 class euni: public epdf
00419 {
00420 protected:
00422 vec low;
00424 vec high;
00426 vec distance;
00428 double nk;
00430 double lnk;
00431 public:
00434 euni ( ) :epdf ( ) {}
00435 euni ( const vec &low0, const vec &high0 ) {set_parameters ( low0,high0 );}
00436 void set_parameters ( const vec &low0, const vec &high0 )
00437 {
00438 distance = high0-low0;
00439 it_assert_debug ( min ( distance ) >0.0,"bad support" );
00440 low = low0;
00441 high = high0;
00442 nk = prod ( 1.0/distance );
00443 lnk = log ( nk );
00444 dim = low.length();
00445 }
00447
00448 double eval ( const vec &val ) const {return nk;}
00449 double evallog ( const vec &val ) const {return lnk;}
00450 vec sample() const
00451 {
00452 vec smp ( dim );
00453 #pragma omp critical
00454 UniRNG.sample_vector ( dim ,smp );
00455 return low+elem_mult ( distance,smp );
00456 }
00458 vec mean() const {return ( high-low ) /2.0;}
00459 vec variance() const {return ( pow ( high,2 ) +pow ( low,2 ) +elem_mult ( high,low ) ) /3.0;}
00460 };
00461
00462
00468 template<class sq_T>
00469 class mlnorm : public mEF
00470 {
00471 protected:
00473 enorm<sq_T> epdf;
00474 mat A;
00475 vec mu_const;
00476 vec& _mu;
00477 public:
00480 mlnorm ( ) :mEF (),epdf ( ),A ( ),_mu ( epdf._mu() ) {ep =&epdf; };
00481 mlnorm ( const mat &A, const vec &mu0, const sq_T &R ) :epdf ( ),_mu ( epdf._mu() )
00482 {
00483 ep =&epdf; set_parameters ( A,mu0,R );
00484 };
00486 void set_parameters ( const mat &A, const vec &mu0, const sq_T &R );
00489 void condition ( const vec &cond );
00490
00492 vec& _mu_const() {return mu_const;}
00494 mat& _A() {return A;}
00496 mat _R() {return epdf._R().to_mat();}
00497
00498 template<class sq_M>
00499 friend std::ostream &operator<< ( std::ostream &os, mlnorm<sq_M> &ml );
00500 };
00501
00503 template<class sq_T>
00504 class mgnorm : public mEF
00505 {
00506 protected:
00508 enorm<sq_T> epdf;
00509 vec μ
00510 fnc* g;
00511 public:
00513 mgnorm() :mu ( epdf._mu() ) {ep=&epdf;}
00515 void set_parameters ( fnc* g0, const sq_T &R0 ) {g=g0; epdf.set_parameters ( zeros ( g->dimension() ), R0 );}
00516 void condition ( const vec &cond ) {mu=g->eval ( cond );};
00517
00518
00546 void from_setting( const Setting &root )
00547 {
00548 fnc* g = UI::build<fnc>( root, "g" );
00549
00550 mat R;
00551 if ( root.exists( "dR" ) )
00552 {
00553 vec dR;
00554 UI::get( dR, root, "dR" );
00555 R=diag(dR);
00556 }
00557 else
00558 UI::get( R, root, "R");
00559
00560 set_parameters(g,R);
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 };
00574
00575 UIREGISTER(mgnorm<chmat>);
00576
00577
00585 class mlstudent : public mlnorm<ldmat>
00586 {
00587 protected:
00588 ldmat Lambda;
00589 ldmat &_R;
00590 ldmat Re;
00591 public:
00592 mlstudent ( ) :mlnorm<ldmat> (),
00593 Lambda (), _R ( epdf._R() ) {}
00594 void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0 )
00595 {
00596 it_assert_debug ( A0.rows() ==mu0.length(),"" );
00597 it_assert_debug ( R0.rows() ==A0.rows(),"" );
00598
00599 epdf.set_parameters ( mu0,Lambda );
00600 A = A0;
00601 mu_const = mu0;
00602 Re=R0;
00603 Lambda = Lambda0;
00604 }
00605 void condition ( const vec &cond )
00606 {
00607 _mu = A*cond + mu_const;
00608 double zeta;
00609
00610 if ( ( cond.length() +1 ) ==Lambda.rows() )
00611 {
00612 zeta = Lambda.invqform ( concat ( cond, vec_1 ( 1.0 ) ) );
00613 }
00614 else
00615 {
00616 zeta = Lambda.invqform ( cond );
00617 }
00618 _R = Re;
00619 _R*= ( 1+zeta );
00620 };
00621
00622 };
00632 class mgamma : public mEF
00633 {
00634 protected:
00636 egamma epdf;
00638 double k;
00640 vec &_beta;
00641
00642 public:
00644 mgamma ( ) : mEF ( ), epdf (), _beta ( epdf._beta() ) {ep=&epdf;};
00646 void set_parameters ( double k, const vec &beta0 );
00647 void condition ( const vec &val ) {_beta=k/val;};
00648 };
00649
00659 class migamma : public mEF
00660 {
00661 protected:
00663 eigamma epdf;
00665 double k;
00667 vec &_alpha;
00669 vec &_beta;
00670
00671 public:
00674 migamma ( ) : mEF (), epdf ( ), _alpha ( epdf._alpha() ), _beta ( epdf._beta() ) {ep=&epdf;};
00675 migamma ( const migamma &m ) : mEF (), epdf ( m.epdf ), _alpha ( epdf._alpha() ), _beta ( epdf._beta() ) {ep=&epdf;};
00677
00679 void set_parameters ( int len, double k0 )
00680 {
00681 k=k0;
00682 epdf.set_parameters ( ( 1.0/ ( k*k ) +2.0 ) *ones ( len ) , ones ( len ) );
00683 dimc = dimension();
00684 };
00685 void condition ( const vec &val )
00686 {
00687 _beta=elem_mult ( val, ( _alpha-1.0 ) );
00688 };
00689 };
00690
00691
00703 class mgamma_fix : public mgamma
00704 {
00705 protected:
00707 double l;
00709 vec refl;
00710 public:
00712 mgamma_fix ( ) : mgamma ( ),refl () {};
00714 void set_parameters ( double k0 , vec ref0, double l0 )
00715 {
00716 mgamma::set_parameters ( k0, ref0 );
00717 refl=pow ( ref0,1.0-l0 );l=l0;
00718 dimc=dimension();
00719 };
00720
00721 void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); _beta=k/mean;};
00722 };
00723
00724
00737 class migamma_ref : public migamma
00738 {
00739 protected:
00741 double l;
00743 vec refl;
00744 public:
00746 migamma_ref ( ) : migamma (),refl ( ) {};
00748 void set_parameters ( double k0 , vec ref0, double l0 )
00749 {
00750 migamma::set_parameters ( ref0.length(), k0 );
00751 refl=pow ( ref0,1.0-l0 );
00752 l=l0;
00753 dimc = dimension();
00754 };
00755
00756 void condition ( const vec &val )
00757 {
00758 vec mean=elem_mult ( refl,pow ( val,l ) );
00759 migamma::condition ( mean );
00760 };
00761
00782 void from_setting( const Setting &root );
00783
00784
00785 };
00786
00787
00788 UIREGISTER(migamma_ref);
00789
00799 class elognorm: public enorm<ldmat>
00800 {
00801 public:
00802 vec sample() const {return exp ( enorm<ldmat>::sample() );};
00803 vec mean() const {vec var=enorm<ldmat>::variance();return exp ( mu - 0.5*var );};
00804
00805 };
00806
00818 class mlognorm : public mpdf
00819 {
00820 protected:
00821 elognorm eno;
00823 double sig2;
00825 vec μ
00826 public:
00828 mlognorm ( ) : eno (), mu ( eno._mu() ) {ep=&eno;};
00830 void set_parameters ( int size, double k )
00831 {
00832 sig2 = 0.5*log ( k*k+1 );
00833 eno.set_parameters ( zeros ( size ),2*sig2*eye ( size ) );
00834
00835 dimc = size;
00836 };
00837
00838 void condition ( const vec &val )
00839 {
00840 mu=log ( val )-sig2;
00841 };
00842
00861 void from_setting( const Setting &root );
00862
00863
00864
00865 };
00866
00867 UIREGISTER(mlognorm);
00868
00872 class eWishartCh : public epdf
00873 {
00874 protected:
00876 chmat Y;
00878 int p;
00880 double delta;
00881 public:
00882 void set_parameters ( const mat &Y0, const double delta0 ) {Y=chmat ( Y0 );delta=delta0; p=Y.rows(); dim = p*p; }
00883 mat sample_mat() const
00884 {
00885 mat X=zeros ( p,p );
00886
00887
00888 for ( int i=0;i<p;i++ )
00889 {
00890 GamRNG.setup ( 0.5* ( delta-i ) , 0.5 );
00891 #pragma omp critical
00892 X ( i,i ) =sqrt ( GamRNG() );
00893 }
00894
00895 for ( int i=0;i<p;i++ )
00896 {
00897 for ( int j=i+1;j<p;j++ )
00898 {
00899 #pragma omp critical
00900 X ( i,j ) =NorRNG.sample();
00901 }
00902 }
00903 return X*Y._Ch();
00904 }
00905 vec sample () const
00906 {
00907 return vec ( sample_mat()._data(),p*p );
00908 }
00910 void setY ( const mat &Ch0 ) {copy_vector ( dim,Ch0._data(), Y._Ch()._data() );}
00912 void _setY ( const vec &ch0 ) {copy_vector ( dim, ch0._data(), Y._Ch()._data() ); }
00914 const chmat& getY()const {return Y;}
00915 };
00916
00917 class eiWishartCh: public epdf
00918 {
00919 protected:
00920 eWishartCh W;
00921 int p;
00922 double delta;
00923 public:
00924 void set_parameters ( const mat &Y0, const double delta0) {
00925 delta = delta0;
00926 W.set_parameters ( inv ( Y0 ),delta0 );
00927 dim = W.dimension(); p=Y0.rows();
00928 }
00929 vec sample() const {mat iCh; iCh=inv ( W.sample_mat() ); return vec ( iCh._data(),dim );}
00930 void _setY ( const vec &y0 )
00931 {
00932 mat Ch ( p,p );
00933 mat iCh ( p,p );
00934 copy_vector ( dim, y0._data(), Ch._data() );
00935
00936 iCh=inv ( Ch );
00937 W.setY ( iCh );
00938 }
00939 virtual double evallog ( const vec &val ) const {
00940 chmat X(p);
00941 const chmat& Y=W.getY();
00942
00943 copy_vector(p*p,val._data(),X._Ch()._data());
00944 chmat iX(p);X.inv(iX);
00945
00946
00947 mat M=Y.to_mat()*iX.to_mat();
00948
00949 double log1 = 0.5*p*(2*Y.logdet())-0.5*(delta+p+1)*(2*X.logdet())-0.5*trace(M);
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959 return log1;
00960 };
00961
00962 };
00963
00964 class rwiWishartCh : public mpdf
00965 {
00966 protected:
00967 eiWishartCh eiW;
00969 double sqd;
00970
00971 vec refl;
00972 double l;
00973 int p;
00974 public:
00975 void set_parameters ( int p0, double k, vec ref0, double l0 )
00976 {
00977 p=p0;
00978 double delta = 2/(k*k)+p+3;
00979 sqd=sqrt ( delta-p-1 );
00980 l=l0;
00981 refl=pow(ref0,1-l);
00982
00983 eiW.set_parameters ( eye ( p ),delta );
00984 ep=&eiW;
00985 dimc=eiW.dimension();
00986 }
00987 void condition ( const vec &c ) {
00988 vec z=c;
00989 int ri=0;
00990 for(int i=0;i<p*p;i+=(p+1)){
00991 z(i) = pow(z(i),l)*refl(ri);
00992 ri++;
00993 }
00994
00995 eiW._setY ( sqd*z );
00996 }
00997 };
00998
01000 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
01006 class eEmp: public epdf
01007 {
01008 protected :
01010 int n;
01012 vec w;
01014 Array<vec> samples;
01015 public:
01018 eEmp ( ) :epdf ( ),w ( ),samples ( ) {};
01019 eEmp ( const eEmp &e ) : epdf ( e ), w ( e.w ), samples ( e.samples ) {};
01021
01023 void set_statistics ( const vec &w0, const epdf* pdf0 );
01025 void set_statistics ( const epdf* pdf0 , int n ) {set_statistics ( ones ( n ) /n,pdf0 );};
01027 void set_samples ( const epdf* pdf0 );
01029 void set_parameters ( int n0, bool copy=true ) {n=n0; w.set_size ( n0,copy );samples.set_size ( n0,copy );};
01031 vec& _w() {return w;};
01033 const vec& _w() const {return w;};
01035 Array<vec>& _samples() {return samples;};
01037 const Array<vec>& _samples() const {return samples;};
01039 ivec resample ( RESAMPLING_METHOD method=SYSTEMATIC );
01041 vec sample() const {it_error ( "Not implemented" );return 0;}
01043 double evallog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
01044 vec mean() const
01045 {
01046 vec pom=zeros ( dim );
01047 for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
01048 return pom;
01049 }
01050 vec variance() const
01051 {
01052 vec pom=zeros ( dim );
01053 for ( int i=0;i<n;i++ ) {pom+=pow ( samples ( i ),2 ) *w ( i );}
01054 return pom-pow ( mean(),2 );
01055 }
01057 void qbounds ( vec &lb, vec &ub, double perc=0.95 ) const
01058 {
01059
01060 lb.set_size ( dim );
01061 ub.set_size ( dim );
01062 lb = std::numeric_limits<double>::infinity();
01063 ub = -std::numeric_limits<double>::infinity();
01064 int j;
01065 for ( int i=0;i<n;i++ )
01066 {
01067 for ( j=0;j<dim; j++ )
01068 {
01069 if ( samples ( i ) ( j ) <lb ( j ) ) {lb ( j ) =samples ( i ) ( j );}
01070 if ( samples ( i ) ( j ) >ub ( j ) ) {ub ( j ) =samples ( i ) ( j );}
01071 }
01072 }
01073 }
01074 };
01075
01076
01078
01079 template<class sq_T>
01080 void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 )
01081 {
01082
01083 mu = mu0;
01084 R = R0;
01085 dim = mu0.length();
01086 };
01087
01088 template<class sq_T>
01089 void enorm<sq_T>::dupdate ( mat &v, double nu )
01090 {
01091
01092 };
01093
01094
01095
01096
01097
01098
01099 template<class sq_T>
01100 vec enorm<sq_T>::sample() const
01101 {
01102 vec x ( dim );
01103 #pragma omp critical
01104 NorRNG.sample_vector ( dim,x );
01105 vec smp = R.sqrt_mult ( x );
01106
01107 smp += mu;
01108 return smp;
01109 };
01110
01111 template<class sq_T>
01112 mat enorm<sq_T>::sample ( int N ) const
01113 {
01114 mat X ( dim,N );
01115 vec x ( dim );
01116 vec pom;
01117 int i;
01118
01119 for ( i=0;i<N;i++ )
01120 {
01121 #pragma omp critical
01122 NorRNG.sample_vector ( dim,x );
01123 pom = R.sqrt_mult ( x );
01124 pom +=mu;
01125 X.set_col ( i, pom );
01126 }
01127
01128 return X;
01129 };
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 template<class sq_T>
01140 double enorm<sq_T>::evallog_nn ( const vec &val ) const
01141 {
01142
01143 double tmp=-0.5* ( R.invqform ( mu-val ) );
01144 return tmp;
01145 };
01146
01147 template<class sq_T>
01148 inline double enorm<sq_T>::lognc () const
01149 {
01150
01151 double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
01152 return tmp;
01153 };
01154
01155 template<class sq_T>
01156 void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 )
01157 {
01158 it_assert_debug ( A0.rows() ==mu0.length(),"" );
01159 it_assert_debug ( A0.rows() ==R0.rows(),"" );
01160
01161 epdf.set_parameters ( zeros ( A0.rows() ),R0 );
01162 A = A0;
01163 mu_const = mu0;
01164 dimc=A0.cols();
01165 }
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192 template<class sq_T>
01193 void mlnorm<sq_T>::condition ( const vec &cond )
01194 {
01195 _mu = A*cond + mu_const;
01196
01197 }
01198
01199 template<class sq_T>
01200 enorm<sq_T>* enorm<sq_T>::marginal ( const RV &rvn ) const
01201 {
01202 it_assert_debug ( isnamed(), "rv description is not assigned" );
01203 ivec irvn = rvn.dataind ( rv );
01204
01205 sq_T Rn ( R,irvn );
01206
01207 enorm<sq_T>* tmp = new enorm<sq_T>;
01208 tmp->set_rv ( rvn );
01209 tmp->set_parameters ( mu ( irvn ), Rn );
01210 return tmp;
01211 }
01212
01213 template<class sq_T>
01214 mpdf* enorm<sq_T>::condition ( const RV &rvn ) const
01215 {
01216
01217 it_assert_debug ( isnamed(),"rvs are not assigned" );
01218
01219 RV rvc = rv.subt ( rvn );
01220 it_assert_debug ( ( rvc._dsize() +rvn._dsize() ==rv._dsize() ),"wrong rvn" );
01221
01222 ivec irvn = rvn.dataind ( rv );
01223 ivec irvc = rvc.dataind ( rv );
01224 ivec perm=concat ( irvn , irvc );
01225 sq_T Rn ( R,perm );
01226
01227
01228 mat S=Rn.to_mat();
01229
01230 int n=rvn._dsize()-1;
01231 int end=R.rows()-1;
01232 mat S11 = S.get ( 0,n, 0, n );
01233 mat S12 = S.get ( 0, n , rvn._dsize(), end );
01234 mat S22 = S.get ( rvn._dsize(), end, rvn._dsize(), end );
01235
01236 vec mu1 = mu ( irvn );
01237 vec mu2 = mu ( irvc );
01238 mat A=S12*inv ( S22 );
01239 sq_T R_n ( S11 - A *S12.T() );
01240
01241 mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( );
01242 tmp->set_rv ( rvn ); tmp->set_rvc ( rvc );
01243 tmp->set_parameters ( A,mu1-A*mu2,R_n );
01244 return tmp;
01245 }
01246
01248
01249 template<class sq_T>
01250 std::ostream &operator<< ( std::ostream &os, mlnorm<sq_T> &ml )
01251 {
01252 os << "A:"<< ml.A<<endl;
01253 os << "mu:"<< ml.mu_const<<endl;
01254 os << "R:" << ml.epdf._R().to_mat() <<endl;
01255 return os;
01256 };
01257
01258 }
01259 #endif //EF_H