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 (){};
00237 mprod (Array<mpdf*> mFacs ){set_elements( mFacs );};
00238 void set_elements(Array<mpdf*> mFacs ) {
00239
00240 set_elements(mFacs);
00241
00242 ep=&dummy;
00243 RV rv=getrv ( true );
00244 set_rv ( rv );dummy.set_parameters ( rv._dsize() );
00245 setrvc ( ep->_rv(),rvc );
00246
00247 for ( int i = 0;i < mpdfs.length(); i++ ) {
00248 dls ( i ) = new datalink_m2m;
00249 dls(i)->set_connection( mpdfs ( i )->_rv(), mpdfs ( i )->_rvc(), _rv(), _rvc() );
00250 }
00251
00252 for ( int i=0; i<mpdfs.length(); i++ ) {
00253 epdfs ( i ) =& ( mpdfs ( i )->_epdf() );
00254 }
00255 };
00256
00257 double evallogcond ( const vec &val, const vec &cond ) {
00258 int i;
00259 double res = 0.0;
00260 for ( i = mpdfs.length() - 1;i >= 0;i-- ) {
00261
00262
00263
00264
00265
00266 res += mpdfs ( i )->evallogcond (
00267 dls ( i )->pushdown ( val ),
00268 dls ( i )->get_cond ( val, cond )
00269 );
00270 }
00271 return res;
00272 }
00273
00274 vec samplecond ( const vec &cond ) {
00276 vec smp= std::numeric_limits<double>::infinity() * ones ( ep->dimension() );
00277 vec smpi;
00278
00279 for ( int i = ( mpdfs.length() - 1 );i >= 0;i-- ) {
00280 if ( mpdfs ( i )->dimensionc() ) {
00281 mpdfs ( i )->condition ( dls ( i )->get_cond ( smp ,cond ) );
00282 }
00283 smpi = epdfs ( i )->sample();
00284
00285 dls ( i )->pushup ( smp, smpi );
00286
00287 }
00288 return smp;
00289 }
00290 mat samplecond ( const vec &cond, int N ) {
00291 mat Smp ( dimension(),N );
00292 for ( int i=0;i<N;i++ ) {Smp.set_col ( i,samplecond ( cond ) );}
00293 return Smp;
00294 }
00295
00296 ~mprod() {};
00297 };
00298
00300 class eprod: public epdf {
00301 protected:
00303 Array<const epdf*> epdfs;
00305 Array<datalink*> dls;
00306 public:
00307 eprod () : epdfs ( 0 ),dls ( 0 ) {};
00308 void set_parameters ( const Array<const epdf*> &epdfs0, bool named=true ) {
00309 epdfs=epdfs0;
00310 dls.set_length ( epdfs.length() );
00311
00312 bool independent=true;
00313 if ( named ) {
00314 for ( int i=0;i<epdfs.length();i++ ) {
00315 independent=rv.add ( epdfs ( i )->_rv() );
00316 it_assert_debug ( independent==true, "eprod:: given components are not independent." );
00317 }
00318 dim=rv._dsize();
00319 }
00320 else {
00321 dim =0; for ( int i=0;i<epdfs.length();i++ ) {
00322 dim+=epdfs ( i )->dimension();
00323 }
00324 }
00325
00326 int cumdim=0;
00327 int dimi=0;
00328 int i;
00329 for ( i=0;i<epdfs.length();i++ ) {
00330 dls ( i ) = new datalink;
00331 if ( named ) {dls ( i )->set_connection ( epdfs ( i )->_rv() , rv );}
00332 else {
00333 dimi = epdfs ( i )->dimension();
00334 dls ( i )->set_connection ( dimi, dim, linspace ( cumdim,cumdim+dimi-1 ) );
00335 cumdim+=dimi;
00336 }
00337 }
00338 }
00339
00340 vec mean() const {
00341 vec tmp ( dim );
00342 for ( int i=0;i<epdfs.length();i++ ) {
00343 vec pom = epdfs ( i )->mean();
00344 dls ( i )->pushup ( tmp, pom );
00345 }
00346 return tmp;
00347 }
00348 vec variance() const {
00349 vec tmp ( dim );
00350 for ( int i=0;i<epdfs.length();i++ ) {
00351 vec pom = epdfs ( i )->mean();
00352 dls ( i )->pushup ( tmp, pow ( pom,2 ) );
00353 }
00354 return tmp-pow ( mean(),2 );
00355 }
00356 vec sample() const {
00357 vec tmp ( dim );
00358 for ( int i=0;i<epdfs.length();i++ ) {
00359 vec pom = epdfs ( i )->sample();
00360 dls ( i )->pushup ( tmp, pom );
00361 }
00362 return tmp;
00363 }
00364 double evallog ( const vec &val ) const {
00365 double tmp=0;
00366 for ( int i=0;i<epdfs.length();i++ ) {
00367 tmp+=epdfs ( i )->evallog ( dls ( i )->pushdown ( val ) );
00368 }
00369 it_assert_debug ( std::isfinite ( tmp ),"Infinite" );
00370 return tmp;
00371 }
00373 const epdf* operator () ( int i ) const {it_assert_debug ( i<epdfs.length(),"wrong index" );return epdfs ( i );}
00374
00376 ~eprod() {for ( int i=0;i<epdfs.length();i++ ) {delete dls ( i );}}
00377 };
00378
00379
00383 class mmix : public mpdf {
00384 protected:
00386 Array<mpdf*> Coms;
00388 emix Epdf;
00389 public:
00391 mmix ( ) : mpdf ( ), Epdf () {ep = &Epdf;};
00393 void set_parameters ( const vec &w, const Array<mpdf*> &Coms ) {
00394 Array<epdf*> Eps ( Coms.length() );
00395
00396 for ( int i = 0;i < Coms.length();i++ ) {
00397 Eps ( i ) = & ( Coms ( i )->_epdf() );
00398 }
00399 Epdf.set_parameters ( w, Eps );
00400 };
00401
00402 void condition ( const vec &cond ) {
00403 for ( int i = 0;i < Coms.length();i++ ) {Coms ( i )->condition ( cond );}
00404 };
00405 };
00406
00407 }
00408 #endif //MX_H