00001 
00013 #ifndef MX_H
00014 #define MX_H
00015 
00016 #include "libBM.h"
00017 #include "libEF.h"
00018 
00019 
00020 namespace bdm {
00021 
00022 
00023 
00036 class mratio: public mpdf {
00037 protected:
00039         const epdf* nom;
00041         epdf* den;
00043         bool destroynom;
00045         datalink_m2e dl;
00046 public:
00049         mratio ( const epdf* nom0, const RV &rv, bool copy=false ) :mpdf ( ), dl ( ) {
00050                 
00051                 rvc = nom0->_rv().subt ( rv );
00052                 dimc = rvc._dsize();
00053                 ep = new epdf;
00054                 ep->set_parameters(rv._dsize());
00055                 ep->set_rv(rv);
00056                 
00057                 
00058                 if ( copy ) {it_error ( "todo" ); destroynom=true; }
00059                 else { nom = nom0; destroynom = false; }
00060                 it_assert_debug ( rvc.length() >0,"Makes no sense to use this object!" );               
00061                 
00062                 
00063                 den = nom->marginal ( rvc );
00064                 dl.set_connection(rv,rvc,nom0->_rv());
00065         };
00066         double evallogcond ( const vec &val, const vec &cond ) {
00067                 double tmp;
00068                 vec nom_val ( ep->dimension() + dimc );
00069                 dl.pushup_cond ( nom_val,val,cond );
00070                 tmp = exp ( nom->evallog ( nom_val ) - den->evallog ( cond ) );
00071                 it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
00072                 return tmp;
00073         }
00075         void ownnom() {destroynom=true;}
00077         ~mratio() {delete den; if ( destroynom ) {delete nom;}}
00078 };
00079 
00090 class emix : public epdf {
00091 protected:
00093         vec w;
00095         Array<epdf*> Coms;
00097         bool destroyComs;
00098 public:
00100         emix ( ) : epdf ( ) {};
00103         void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy=false );
00104 
00105         vec sample() const;
00106         vec mean() const {
00107                 int i; vec mu = zeros ( dim );
00108                 for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); }
00109                 return mu;
00110         }
00111         vec variance() const {
00112                 
00113                 vec mom2 = zeros ( dim );
00114                 for ( int i = 0;i < w.length();i++ ) {mom2 += w ( i ) * (Coms(i)->variance() + pow ( Coms ( i )->mean(),2 )); }
00115                 
00116                 return mom2-pow ( mean(),2 );
00117         }
00118         double evallog ( const vec &val ) const {
00119                 int i;
00120                 double sum = 0.0;
00121                 for ( i = 0;i < w.length();i++ ) {sum += w ( i ) * exp ( Coms ( i )->evallog ( val ) );}
00122                 if ( sum==0.0 ) {sum=std::numeric_limits<double>::epsilon();}
00123                 double tmp=log ( sum );
00124                 it_assert_debug ( std::isfinite ( tmp ),"Infinite" );
00125                 return tmp;
00126         };
00127         vec evallog_m ( const mat &Val ) const {
00128                 vec x=zeros ( Val.cols() );
00129                 for ( int i = 0; i < w.length(); i++ ) {
00130                         x+= w ( i ) *exp ( Coms ( i )->evallog_m ( Val ) );
00131                 }
00132                 return log ( x );
00133         };
00135         mat evallog_M ( const mat &Val ) const {
00136                 mat X ( w.length(), Val.cols() );
00137                 for ( int i = 0; i < w.length(); i++ ) {
00138                         X.set_row ( i, w ( i ) *exp ( Coms ( i )->evallog_m ( Val ) ) );
00139                 }
00140                 return X;
00141         };
00142 
00143         emix* marginal ( const RV &rv ) const;
00144         mratio* condition ( const RV &rv ) const; 
00145 
00146 
00148         vec& _w() {return w;}
00149         virtual ~emix() {if ( destroyComs ) {for ( int i=0;i<Coms.length();i++ ) {delete Coms ( i );}}}
00151         void ownComs() {destroyComs=true;}
00152 
00154         epdf* _Coms ( int i ) {return Coms ( i );}
00155         void set_rv(const RV &rv){
00156                 epdf::set_rv(rv);
00157                 for(int i=0;i<Coms.length();i++){Coms(i)->set_rv(rv);}
00158         }
00159 };
00160 
00169 class mprod: public compositepdf, public mpdf {
00170 protected:
00172         Array<epdf*> epdfs;
00174         Array<datalink_m2m*> dls;
00176         epdf dummy;
00177 public:
00180         mprod ( Array<mpdf*> mFacs ) : compositepdf ( mFacs ), mpdf (), epdfs ( n ), dls ( n ) {
00181                 ep=&dummy;
00182                 RV rv=getrv ( true );
00183                 set_rv ( rv );dummy.set_parameters ( rv._dsize() );
00184                 setrvc ( ep->_rv(),rvc );
00185                 
00186                 for ( int i = 0;i < n;i++ ) {
00187                         dls ( i ) = new datalink_m2m;
00188                         dls(i)->set_connection( mpdfs ( i )->_rv(), mpdfs ( i )->_rvc(), _rv(), _rvc() );
00189                 }
00190 
00191                 for ( int i=0;i<n;i++ ) {
00192                         epdfs ( i ) =& ( mpdfs ( i )->_epdf() );
00193                 }
00194         };
00195 
00196         double evallogcond ( const vec &val, const vec &cond ) {
00197                 int i;
00198                 double res = 0.0;
00199                 for ( i = n - 1;i >= 0;i-- ) {
00200                         
00201 
00202 
00203 
00204 
00205                         res += mpdfs ( i )->evallogcond (
00206                                    dls ( i )->pushdown ( val ),
00207                                    dls ( i )->get_cond ( val, cond )
00208                                );
00209                 }
00210                 return res;
00211         }
00212         
00213         vec samplecond ( const vec &cond ) {
00215                 vec smp= std::numeric_limits<double>::infinity() * ones ( ep->dimension() );
00216                 vec smpi;
00217                 
00218                 for ( int i = ( n - 1 );i >= 0;i-- ) {
00219                         if ( mpdfs ( i )->dimensionc() ) {
00220                                 mpdfs ( i )->condition ( dls ( i )->get_cond ( smp ,cond ) ); 
00221                         }
00222                         smpi = epdfs ( i )->sample();
00223                         
00224                         dls ( i )->pushup ( smp, smpi );
00225                         
00226                 }
00227                 return smp;
00228         }
00229         mat samplecond ( const vec &cond,  int N ) {
00230                 mat Smp ( dimension(),N );
00231                 for ( int i=0;i<N;i++ ) {Smp.set_col ( i,samplecond ( cond ) );}
00232                 return Smp;
00233         }
00234 
00235         ~mprod() {};
00236 };
00237 
00239 class eprod: public epdf {
00240 protected:
00242         Array<const epdf*> epdfs;
00244         Array<datalink*> dls;
00245 public:
00246         eprod () : epdfs ( 0 ),dls ( 0 ) {};
00247         void set_parameters ( const Array<const epdf*> &epdfs0, bool named=true ) {
00248                 epdfs=epdfs0;
00249                 dls.set_length ( epdfs.length() );
00250 
00251                 bool independent=true;
00252                 if ( named ) {
00253                         for ( int i=0;i<epdfs.length();i++ ) {
00254                                 independent=rv.add ( epdfs ( i )->_rv() );
00255                                 it_assert_debug ( independent==true, "eprod:: given components are not independent." );
00256                         }
00257                         dim=rv._dsize();
00258                 }
00259                 else {
00260                         dim =0; for ( int i=0;i<epdfs.length();i++ ) {
00261                                 dim+=epdfs ( i )->dimension();
00262                         }
00263                 }
00264                 
00265                 int cumdim=0;
00266                 int dimi=0;
00267                 int i;
00268                 for ( i=0;i<epdfs.length();i++ ) {
00269                         dls ( i ) = new datalink;
00270                         if ( named ) {dls ( i )->set_connection ( epdfs ( i )->_rv() , rv );}
00271                         else {
00272                                 dimi = epdfs ( i )->dimension();
00273                                 dls ( i )->set_connection ( dimi, dim, linspace ( cumdim,cumdim+dimi-1 ) );
00274                                 cumdim+=dimi;
00275                         }
00276                 }
00277         }
00278 
00279         vec mean() const {
00280                 vec tmp ( dim );
00281                 for ( int i=0;i<epdfs.length();i++ ) {
00282                         vec pom = epdfs ( i )->mean();
00283                         dls ( i )->pushup ( tmp, pom );
00284                 }
00285                 return tmp;
00286         }
00287         vec variance() const {
00288                 vec tmp ( dim ); 
00289                 for ( int i=0;i<epdfs.length();i++ ) {
00290                         vec pom = epdfs ( i )->mean();
00291                         dls ( i )->pushup ( tmp, pow ( pom,2 ) );
00292                 }
00293                 return tmp-pow ( mean(),2 );
00294         }
00295         vec sample() const {
00296                 vec tmp ( dim );
00297                 for ( int i=0;i<epdfs.length();i++ ) {
00298                         vec pom = epdfs ( i )->sample();
00299                         dls ( i )->pushup ( tmp, pom );
00300                 }
00301                 return tmp;
00302         }
00303         double evallog ( const vec &val ) const {
00304                 double tmp=0;
00305                 for ( int i=0;i<epdfs.length();i++ ) {
00306                         tmp+=epdfs ( i )->evallog ( dls ( i )->pushdown ( val ) );
00307                 }
00308                 it_assert_debug ( std::isfinite ( tmp ),"Infinite" );
00309                 return tmp;
00310         }
00312         const epdf* operator () ( int i ) const {it_assert_debug ( i<epdfs.length(),"wrong index" );return epdfs ( i );}
00313 
00315         ~eprod() {for ( int i=0;i<epdfs.length();i++ ) {delete dls ( i );}}
00316 };
00317 
00318 
00322 class mmix : public mpdf {
00323 protected:
00325         Array<mpdf*> Coms;
00327         emix Epdf;
00328 public:
00330         mmix ( ) : mpdf ( ), Epdf () {ep = &Epdf;};
00332         void set_parameters ( const vec &w, const Array<mpdf*> &Coms ) {
00333                 Array<epdf*> Eps ( Coms.length() );
00334 
00335                 for ( int i = 0;i < Coms.length();i++ ) {
00336                         Eps ( i ) = & ( Coms ( i )->_epdf() );
00337                 }
00338                 Epdf.set_parameters ( w, Eps );
00339         };
00340 
00341         void condition ( const vec &cond ) {
00342                 for ( int i = 0;i < Coms.length();i++ ) {Coms ( i )->condition ( cond );}
00343         };
00344 };
00345 
00346 }
00347 #endif //MX_H