00001 
00013 #ifndef EMIX_H
00014 #define EMIX_H
00015 
00016 #define LOG2  0.69314718055995
00017 
00018 #include "../shared_ptr.h"
00019 #include "exp_family.h"
00020 
00021 namespace bdm {
00022 
00023 
00024 
00037 class mratio: public mpdf {
00038 protected:
00040         const epdf* nom;
00041 
00043         shared_ptr<epdf> den;
00044 
00046         bool destroynom;
00048         datalink_m2e dl;
00050         epdf iepdf;
00051 public:
00054         mratio ( const epdf* nom0, const RV &rv, bool copy = false ) : mpdf ( ), dl ( ),iepdf() {
00055                 
00056                 rvc = nom0->_rv().subt ( rv );
00057                 dimc = rvc._dsize();
00058                 set_ep ( iepdf );
00059                 iepdf.set_parameters ( rv._dsize() );
00060                 iepdf.set_rv ( rv );
00061 
00062                 
00063                 if ( copy ) {
00064                         it_error ( "todo" );
00065                         destroynom = true;
00066                 } else {
00067                         nom = nom0;
00068                         destroynom = false;
00069                 }
00070                 it_assert_debug ( rvc.length() > 0, "Makes no sense to use this object!" );
00071 
00072                 
00073                 den = nom->marginal ( rvc );
00074                 dl.set_connection ( rv, rvc, nom0->_rv() );
00075         };
00076         double evallogcond ( const vec &val, const vec &cond ) {
00077                 double tmp;
00078                 vec nom_val ( dimension() + dimc );
00079                 dl.pushup_cond ( nom_val, val, cond );
00080                 tmp = exp ( nom->evallog ( nom_val ) - den->evallog ( cond ) );
00081                 return tmp;
00082         }
00084         void ownnom() {
00085                 destroynom = true;
00086         }
00088         ~mratio() {
00089                 if ( destroynom ) {
00090                         delete nom;
00091                 }
00092         }
00093 };
00094 
00105 class emix : public epdf {
00106 protected:
00108         vec w;
00110         Array<shared_ptr<epdf> > Coms;
00111 
00112 public:
00114         emix ( ) : epdf ( ) {};
00117         void set_parameters ( const vec &w, const Array<shared_ptr<epdf> > &Coms );
00118 
00119         vec sample() const;
00120         vec mean() const {
00121                 int i;
00122                 vec mu = zeros ( dim );
00123                 for ( i = 0; i < w.length(); i++ ) {
00124                         mu += w ( i ) * Coms ( i )->mean();
00125                 }
00126                 return mu;
00127         }
00128         vec variance() const {
00129                 
00130                 vec mom2 = zeros ( dim );
00131                 for ( int i = 0; i < w.length(); i++ ) {
00132                         mom2 += w ( i ) * ( Coms ( i )->variance() + pow ( Coms ( i )->mean(), 2 ) );
00133                 }
00134                 
00135                 return mom2 - pow ( mean(), 2 );
00136         }
00137         double evallog ( const vec &val ) const {
00138                 int i;
00139                 double sum = 0.0;
00140                 for ( i = 0; i < w.length(); i++ ) {
00141                         sum += w ( i ) * exp ( Coms ( i )->evallog ( val ) );
00142                 }
00143                 if ( sum == 0.0 ) {
00144                         sum = std::numeric_limits<double>::epsilon();
00145                 }
00146                 double tmp = log ( sum );
00147                 it_assert_debug ( std::isfinite ( tmp ), "Infinite" );
00148                 return tmp;
00149         };
00150         vec evallog_m ( const mat &Val ) const {
00151                 vec x = zeros ( Val.cols() );
00152                 for ( int i = 0; i < w.length(); i++ ) {
00153                         x += w ( i ) * exp ( Coms ( i )->evallog_m ( Val ) );
00154                 }
00155                 return log ( x );
00156         };
00158         mat evallog_M ( const mat &Val ) const {
00159                 mat X ( w.length(), Val.cols() );
00160                 for ( int i = 0; i < w.length(); i++ ) {
00161                         X.set_row ( i, w ( i ) *exp ( Coms ( i )->evallog_m ( Val ) ) );
00162                 }
00163                 return X;
00164         };
00165 
00166         shared_ptr<epdf> marginal ( const RV &rv ) const;
00168         void marginal ( const RV &rv, emix &target ) const;
00169         shared_ptr<mpdf> condition ( const RV &rv ) const;
00170 
00171 
00173         vec& _w() {
00174                 return w;
00175         }
00176 
00178         shared_ptr<epdf> _Coms ( int i ) {
00179                 return Coms ( i );
00180         }
00181 
00182         void set_rv ( const RV &rv ) {
00183                 epdf::set_rv ( rv );
00184                 for ( int i = 0; i < Coms.length(); i++ ) {
00185                         Coms ( i )->set_rv ( rv );
00186                 }
00187         }
00188 };
00189 SHAREDPTR( emix );
00190 
00195 class egiwmix : public egiw {
00196 protected:
00198         vec w;
00200         Array<egiw*> Coms;
00202         bool destroyComs;
00203 public:
00205         egiwmix ( ) : egiw ( ) {};
00206 
00209         void set_parameters ( const vec &w, const Array<egiw*> &Coms, bool copy = false );
00210 
00212         vec mean() const;
00213 
00215         vec sample() const;
00216 
00218         vec variance() const;
00219 
00220         
00221         void mean_mat ( mat &M, mat&R ) const {};
00222         double evallog_nn ( const vec &val ) const {
00223                 return 0;
00224         };
00225         double lognc () const {
00226                 return 0;
00227         }
00228 
00229         shared_ptr<epdf> marginal ( const RV &rv ) const;
00230         void marginal ( const RV &rv, emix &target ) const;
00231 
00232 
00234         vec& _w() {
00235                 return w;
00236         }
00237         virtual ~egiwmix() {
00238                 if ( destroyComs ) {
00239                         for ( int i = 0; i < Coms.length(); i++ ) {
00240                                 delete Coms ( i );
00241                         }
00242                 }
00243         }
00245         void ownComs() {
00246                 destroyComs = true;
00247         }
00248 
00250         egiw* _Coms ( int i ) {
00251                 return Coms ( i );
00252         }
00253 
00254         void set_rv ( const RV &rv ) {
00255                 egiw::set_rv ( rv );
00256                 for ( int i = 0; i < Coms.length(); i++ ) {
00257                         Coms ( i )->set_rv ( rv );
00258                 }
00259         }
00260 
00262         egiw* approx();
00263 };
00264 
00273 class mprod: public mpdf {
00274 private:
00275         Array<shared_ptr<mpdf> > mpdfs;
00276 
00277 protected:
00279         Array<datalink_m2m*> dls;
00280 
00282         epdf iepdf;
00283 
00284 public:
00286         mprod() { }
00287 
00290         mprod ( const Array<shared_ptr<mpdf> > &mFacs ) {
00291                 set_elements ( mFacs );
00292         }
00294         void set_elements (const Array<shared_ptr<mpdf> > &mFacs );
00295 
00296         double evallogcond ( const vec &val, const vec &cond ) {
00297                 int i;
00298                 double res = 0.0;
00299                 for ( i = mpdfs.length() - 1; i >= 0; i-- ) {
00300                         
00301 
00302 
00303 
00304 
00305                         res += mpdfs ( i )->evallogcond (
00306                                    dls ( i )->pushdown ( val ),
00307                                    dls ( i )->get_cond ( val, cond )
00308                                );
00309                 }
00310                 return res;
00311         }
00312         vec evallogcond_m ( const mat &Dt, const vec &cond ) {
00313                 vec tmp ( Dt.cols() );
00314                 for ( int i = 0; i < Dt.cols(); i++ ) {
00315                         tmp ( i ) = evallogcond ( Dt.get_col ( i ), cond );
00316                 }
00317                 return tmp;
00318         };
00319         vec evallogcond_m ( const Array<vec> &Dt, const vec &cond ) {
00320                 vec tmp ( Dt.length() );
00321                 for ( int i = 0; i < Dt.length(); i++ ) {
00322                         tmp ( i ) = evallogcond ( Dt ( i ), cond );
00323                 }
00324                 return tmp;
00325         };
00326 
00327 
00328         
00329         vec samplecond ( const vec &cond ) {
00331                 vec smp = std::numeric_limits<double>::infinity() * ones ( dimension() );
00332                 vec smpi;
00333                 
00334                 for ( int i = ( mpdfs.length() - 1 ); i >= 0; i-- ) {
00335                         
00336                         smpi = mpdfs(i)->samplecond(dls ( i )->get_cond ( smp , cond ));                        
00337                         
00338                         dls ( i )->pushup ( smp, smpi );
00339                 }
00340                 return smp;
00341         }
00342         mat samplecond ( const vec &cond,  int N ) {
00343                 mat Smp ( dimension(), N );
00344                 for ( int i = 0; i < N; i++ ) {
00345                         Smp.set_col ( i, samplecond ( cond ) );
00346                 }
00347                 return Smp;
00348         }
00349 
00357         void from_setting ( const Setting &set ) {
00358                 Array<shared_ptr<mpdf> > atmp; 
00359                 UI::get ( atmp, set, "mpdfs", UI::compulsory );
00360                 set_elements ( atmp );
00361         }
00362 
00363 };
00364 UIREGISTER ( mprod );
00365 SHAREDPTR ( mprod );
00366 
00368 class eprod: public epdf {
00369 protected:
00371         Array<const epdf*> epdfs;
00373         Array<datalink*> dls;
00374 public:
00376         eprod () : epdfs ( 0 ), dls ( 0 ) {};
00378         void set_parameters ( const Array<const epdf*> &epdfs0, bool named = true ) {
00379                 epdfs = epdfs0;
00380                 dls.set_length ( epdfs.length() );
00381 
00382                 bool independent = true;
00383                 if ( named ) {
00384                         for ( int i = 0; i < epdfs.length(); i++ ) {
00385                                 independent = rv.add ( epdfs ( i )->_rv() );
00386                                 it_assert_debug ( independent == true, "eprod:: given components are not independent." );
00387                         }
00388                         dim = rv._dsize();
00389                 } else {
00390                         dim = 0;
00391                         for ( int i = 0; i < epdfs.length(); i++ ) {
00392                                 dim += epdfs ( i )->dimension();
00393                         }
00394                 }
00395                 
00396                 int cumdim = 0;
00397                 int dimi = 0;
00398                 int i;
00399                 for ( i = 0; i < epdfs.length(); i++ ) {
00400                         dls ( i ) = new datalink;
00401                         if ( named ) {
00402                                 dls ( i )->set_connection ( epdfs ( i )->_rv() , rv );
00403                         } else {
00404                                 dimi = epdfs ( i )->dimension();
00405                                 dls ( i )->set_connection ( dimi, dim, linspace ( cumdim, cumdim + dimi - 1 ) );
00406                                 cumdim += dimi;
00407                         }
00408                 }
00409         }
00410 
00411         vec mean() const {
00412                 vec tmp ( dim );
00413                 for ( int i = 0; i < epdfs.length(); i++ ) {
00414                         vec pom = epdfs ( i )->mean();
00415                         dls ( i )->pushup ( tmp, pom );
00416                 }
00417                 return tmp;
00418         }
00419         vec variance() const {
00420                 vec tmp ( dim ); 
00421                 for ( int i = 0; i < epdfs.length(); i++ ) {
00422                         vec pom = epdfs ( i )->mean();
00423                         dls ( i )->pushup ( tmp, pow ( pom, 2 ) );
00424                 }
00425                 return tmp - pow ( mean(), 2 );
00426         }
00427         vec sample() const {
00428                 vec tmp ( dim );
00429                 for ( int i = 0; i < epdfs.length(); i++ ) {
00430                         vec pom = epdfs ( i )->sample();
00431                         dls ( i )->pushup ( tmp, pom );
00432                 }
00433                 return tmp;
00434         }
00435         double evallog ( const vec &val ) const {
00436                 double tmp = 0;
00437                 for ( int i = 0; i < epdfs.length(); i++ ) {
00438                         tmp += epdfs ( i )->evallog ( dls ( i )->pushdown ( val ) );
00439                 }
00440                 it_assert_debug ( std::isfinite ( tmp ), "Infinite" );
00441                 return tmp;
00442         }
00444         const epdf* operator () ( int i ) const {
00445                 it_assert_debug ( i < epdfs.length(), "wrong index" );
00446                 return epdfs ( i );
00447         }
00448 
00450         ~eprod() {
00451                 for ( int i = 0; i < epdfs.length(); i++ ) {
00452                         delete dls ( i );
00453                 }
00454         }
00455 };
00456 
00457 
00461 class mmix : public mpdf {
00462 protected:
00464         Array<shared_ptr<mpdf> > Coms;
00466         vec w;
00468         epdf dummy_epdf;
00469 public:
00471         mmix() : Coms(0), dummy_epdf() { set_ep(dummy_epdf);    }
00472 
00474         void set_parameters ( const vec &w0, const Array<shared_ptr<mpdf> > &Coms0 ) {
00476                 Coms = Coms0;
00477                 w=w0;   
00478 
00479                 if (Coms0.length()>0){
00480                         set_rv(Coms(0)->_rv());
00481                         dummy_epdf.set_parameters(Coms(0)->_rv()._dsize());
00482                         set_rvc(Coms(0)->_rvc());
00483                         dimc = rvc._dsize();
00484                 }
00485         }
00486         double evallogcond (const vec &dt, const vec &cond) {
00487                 double ll=0.0;
00488                 for (int i=0;i<Coms.length();i++){
00489                         ll+=Coms(i)->evallogcond(dt,cond);
00490                 }
00491                 return ll;
00492         }
00493 
00494         vec samplecond (const vec &cond);
00495 
00496 };
00497 
00498 }
00499 #endif //MX_H