00001
00013 #ifndef MX_H
00014 #define MX_H
00015
00016 #define LOG2 0.69314718055995
00017
00018 #include "libEF.h"
00019
00020
00021 namespace bdm {
00022
00023
00024
00037 class mratio: public mpdf {
00038 protected:
00040 const epdf* nom;
00042 epdf* den;
00044 bool destroynom;
00046 datalink_m2e dl;
00047 public:
00050 mratio ( const epdf* nom0, const RV &rv, bool copy=false ) :mpdf ( ), dl ( ) {
00051
00052 rvc = nom0->_rv().subt ( rv );
00053 dimc = rvc._dsize();
00054 ep = new epdf;
00055 ep->set_parameters(rv._dsize());
00056 ep->set_rv(rv);
00057
00058
00059 if ( copy ) {it_error ( "todo" ); destroynom=true; }
00060 else { nom = nom0; destroynom = false; }
00061 it_assert_debug ( rvc.length() >0,"Makes no sense to use this object!" );
00062
00063
00064 den = nom->marginal ( rvc );
00065 dl.set_connection(rv,rvc,nom0->_rv());
00066 };
00067 double evallogcond ( const vec &val, const vec &cond ) {
00068 double tmp;
00069 vec nom_val ( ep->dimension() + dimc );
00070 dl.pushup_cond ( nom_val,val,cond );
00071 tmp = exp ( nom->evallog ( nom_val ) - den->evallog ( cond ) );
00072 it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
00073 return tmp;
00074 }
00076 void ownnom() {destroynom=true;}
00078 ~mratio() {delete den; if ( destroynom ) {delete nom;}}
00079 };
00080
00091 class emix : public epdf {
00092 protected:
00094 vec w;
00096 Array<epdf*> Coms;
00098 bool destroyComs;
00099 public:
00101 emix ( ) : epdf ( ) {};
00104 void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy=false );
00105
00106 vec sample() const;
00107 vec mean() const {
00108 int i; vec mu = zeros ( dim );
00109 for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); }
00110 return mu;
00111 }
00112 vec variance() const {
00113
00114 vec mom2 = zeros ( dim );
00115 for ( int i = 0;i < w.length();i++ ) {mom2 += w ( i ) * (Coms(i)->variance() + pow ( Coms ( i )->mean(),2 )); }
00116
00117 return mom2-pow ( mean(),2 );
00118 }
00119 double evallog ( const vec &val ) const {
00120 int i;
00121 double sum = 0.0;
00122 for ( i = 0;i < w.length();i++ ) {sum += w ( i ) * exp ( Coms ( i )->evallog ( val ) );}
00123 if ( sum==0.0 ) {sum=std::numeric_limits<double>::epsilon();}
00124 double tmp=log ( sum );
00125 it_assert_debug ( std::isfinite ( tmp ),"Infinite" );
00126 return tmp;
00127 };
00128 vec evallog_m ( const mat &Val ) const {
00129 vec x=zeros ( Val.cols() );
00130 for ( int i = 0; i < w.length(); i++ ) {
00131 x+= w ( i ) *exp ( Coms ( i )->evallog_m ( Val ) );
00132 }
00133 return log ( x );
00134 };
00136 mat evallog_M ( const mat &Val ) const {
00137 mat X ( w.length(), Val.cols() );
00138 for ( int i = 0; i < w.length(); i++ ) {
00139 X.set_row ( i, w ( i ) *exp ( Coms ( i )->evallog_m ( Val ) ) );
00140 }
00141 return X;
00142 };
00143
00144 emix* marginal ( const RV &rv ) const;
00145 mratio* condition ( const RV &rv ) const;
00146
00147
00149 vec& _w() {return w;}
00150 virtual ~emix() {if ( destroyComs ) {for ( int i=0;i<Coms.length();i++ ) {delete Coms ( i );}}}
00152 void ownComs() {destroyComs=true;}
00153
00155 epdf* _Coms ( int i ) {return Coms ( i );}
00156 void set_rv(const RV &rv){
00157 epdf::set_rv(rv);
00158 for(int i=0;i<Coms.length();i++){Coms(i)->set_rv(rv);}
00159 }
00160 };
00161
00162
00167 class egiwmix : public egiw {
00168 protected:
00170 vec w;
00172 Array<egiw*> Coms;
00174 bool destroyComs;
00175 public:
00177 egiwmix ( ) : egiw ( ) {};
00178
00181 void set_parameters ( const vec &w, const Array<egiw*> &Coms, bool copy=false );
00182
00184 vec mean() const;
00185
00187 vec sample() const;
00188
00190 vec variance() const;
00191
00192
00193 void mean_mat ( mat &M, mat&R ) const {};
00194 double evallog_nn ( const vec &val ) const {return 0;};
00195 double lognc () const {return 0;};
00196 emix* marginal ( const RV &rv ) const;
00197
00198
00200 vec& _w() {return w;}
00201 virtual ~egiwmix() {if ( destroyComs ) {for ( int i=0;i<Coms.length();i++ ) {delete Coms ( i );}}}
00203 void ownComs() {destroyComs=true;}
00204
00206 egiw* _Coms ( int i ) {return Coms ( i );}
00207
00208 void set_rv(const RV &rv){
00209 egiw::set_rv(rv);
00210 for(int i=0;i<Coms.length();i++){Coms(i)->set_rv(rv);}
00211 }
00212
00214 egiw* approx();
00215 };
00216
00225 class mprod: public compositepdf, public mpdf {
00226 protected:
00228 Array<epdf*> epdfs;
00230 Array<datalink_m2m*> dls;
00232 epdf dummy;
00233 public:
00236 mprod ( Array<mpdf*> mFacs ) : compositepdf ( mFacs ), mpdf (), epdfs ( n ), dls ( n ) {
00237 ep=&dummy;
00238 RV rv=getrv ( true );
00239 set_rv ( rv );dummy.set_parameters ( rv._dsize() );
00240 setrvc ( ep->_rv(),rvc );
00241
00242 for ( int i = 0;i < n;i++ ) {
00243 dls ( i ) = new datalink_m2m;
00244 dls(i)->set_connection( mpdfs ( i )->_rv(), mpdfs ( i )->_rvc(), _rv(), _rvc() );
00245 }
00246
00247 for ( int i=0;i<n;i++ ) {
00248 epdfs ( i ) =& ( mpdfs ( i )->_epdf() );
00249 }
00250 };
00251
00252 double evallogcond ( const vec &val, const vec &cond ) {
00253 int i;
00254 double res = 0.0;
00255 for ( i = n - 1;i >= 0;i-- ) {
00256
00257
00258
00259
00260
00261 res += mpdfs ( i )->evallogcond (
00262 dls ( i )->pushdown ( val ),
00263 dls ( i )->get_cond ( val, cond )
00264 );
00265 }
00266 return res;
00267 }
00268
00269 vec samplecond ( const vec &cond ) {
00271 vec smp= std::numeric_limits<double>::infinity() * ones ( ep->dimension() );
00272 vec smpi;
00273
00274 for ( int i = ( n - 1 );i >= 0;i-- ) {
00275 if ( mpdfs ( i )->dimensionc() ) {
00276 mpdfs ( i )->condition ( dls ( i )->get_cond ( smp ,cond ) );
00277 }
00278 smpi = epdfs ( i )->sample();
00279
00280 dls ( i )->pushup ( smp, smpi );
00281
00282 }
00283 return smp;
00284 }
00285 mat samplecond ( const vec &cond, int N ) {
00286 mat Smp ( dimension(),N );
00287 for ( int i=0;i<N;i++ ) {Smp.set_col ( i,samplecond ( cond ) );}
00288 return Smp;
00289 }
00290
00291 ~mprod() {};
00292 };
00293
00295 class eprod: public epdf {
00296 protected:
00298 Array<const epdf*> epdfs;
00300 Array<datalink*> dls;
00301 public:
00302 eprod () : epdfs ( 0 ),dls ( 0 ) {};
00303 void set_parameters ( const Array<const epdf*> &epdfs0, bool named=true ) {
00304 epdfs=epdfs0;
00305 dls.set_length ( epdfs.length() );
00306
00307 bool independent=true;
00308 if ( named ) {
00309 for ( int i=0;i<epdfs.length();i++ ) {
00310 independent=rv.add ( epdfs ( i )->_rv() );
00311 it_assert_debug ( independent==true, "eprod:: given components are not independent." );
00312 }
00313 dim=rv._dsize();
00314 }
00315 else {
00316 dim =0; for ( int i=0;i<epdfs.length();i++ ) {
00317 dim+=epdfs ( i )->dimension();
00318 }
00319 }
00320
00321 int cumdim=0;
00322 int dimi=0;
00323 int i;
00324 for ( i=0;i<epdfs.length();i++ ) {
00325 dls ( i ) = new datalink;
00326 if ( named ) {dls ( i )->set_connection ( epdfs ( i )->_rv() , rv );}
00327 else {
00328 dimi = epdfs ( i )->dimension();
00329 dls ( i )->set_connection ( dimi, dim, linspace ( cumdim,cumdim+dimi-1 ) );
00330 cumdim+=dimi;
00331 }
00332 }
00333 }
00334
00335 vec mean() const {
00336 vec tmp ( dim );
00337 for ( int i=0;i<epdfs.length();i++ ) {
00338 vec pom = epdfs ( i )->mean();
00339 dls ( i )->pushup ( tmp, pom );
00340 }
00341 return tmp;
00342 }
00343 vec variance() const {
00344 vec tmp ( dim );
00345 for ( int i=0;i<epdfs.length();i++ ) {
00346 vec pom = epdfs ( i )->mean();
00347 dls ( i )->pushup ( tmp, pow ( pom,2 ) );
00348 }
00349 return tmp-pow ( mean(),2 );
00350 }
00351 vec sample() const {
00352 vec tmp ( dim );
00353 for ( int i=0;i<epdfs.length();i++ ) {
00354 vec pom = epdfs ( i )->sample();
00355 dls ( i )->pushup ( tmp, pom );
00356 }
00357 return tmp;
00358 }
00359 double evallog ( const vec &val ) const {
00360 double tmp=0;
00361 for ( int i=0;i<epdfs.length();i++ ) {
00362 tmp+=epdfs ( i )->evallog ( dls ( i )->pushdown ( val ) );
00363 }
00364 it_assert_debug ( std::isfinite ( tmp ),"Infinite" );
00365 return tmp;
00366 }
00368 const epdf* operator () ( int i ) const {it_assert_debug ( i<epdfs.length(),"wrong index" );return epdfs ( i );}
00369
00371 ~eprod() {for ( int i=0;i<epdfs.length();i++ ) {delete dls ( i );}}
00372 };
00373
00374
00378 class mmix : public mpdf {
00379 protected:
00381 Array<mpdf*> Coms;
00383 emix Epdf;
00384 public:
00386 mmix ( ) : mpdf ( ), Epdf () {ep = &Epdf;};
00388 void set_parameters ( const vec &w, const Array<mpdf*> &Coms ) {
00389 Array<epdf*> Eps ( Coms.length() );
00390
00391 for ( int i = 0;i < Coms.length();i++ ) {
00392 Eps ( i ) = & ( Coms ( i )->_epdf() );
00393 }
00394 Epdf.set_parameters ( w, Eps );
00395 };
00396
00397 void condition ( const vec &cond ) {
00398 for ( int i = 0;i < Coms.length();i++ ) {Coms ( i )->condition ( cond );}
00399 };
00400 };
00401
00402 }
00403 #endif //MX_H