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 ( rv,nom0->_rv().subt ( rv ) ), dl ( rv,rvc,nom0->_rv() ) {
00050                 if ( copy ) {
00051 
00052                         it_error ( "todo" );
00053                         destroynom=true;
00054                 }
00055                 else {
00056                         nom = nom0;
00057                         destroynom = false;
00058                 }
00059                 it_assert_debug ( rvc.length() >0,"Makes no sense to use this object!" );
00060                 den = nom->marginal ( rvc );
00061         };
00062         double evallogcond ( const vec &val, const vec &cond ) {
00063                 double tmp;
00064                 vec nom_val ( rv.count() +rvc.count() );
00065                 dl.fill_val_cond ( nom_val,val,cond );
00066                 tmp = exp ( nom->evallog ( nom_val ) - den->evallog ( cond ) );
00067                 it_assert_debug(std::isfinite(tmp),"Infinite value");
00068                 return tmp;
00069         }
00071         void ownnom() {destroynom=true;}
00073         ~mratio() {delete den; if ( destroynom ) {delete nom;}}
00074 };
00075 
00086 class emix : public epdf {
00087 protected:
00089         vec w;
00091         Array<epdf*> Coms;
00093         bool destroyComs;
00094 public:
00096         emix ( const RV &rv ) : epdf ( rv ) {};
00099         void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy=true );
00100 
00101         vec sample() const;
00102         vec mean() const {
00103                 int i; vec mu = zeros ( rv.count() );
00104                 for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); }
00105                 return mu;
00106         }
00107         vec variance() const {
00108                 
00109                 vec mom2 = zeros(rv.count());
00110                 for ( int i = 0;i < w.length();i++ ) {mom2 += w ( i ) * pow(Coms ( i )->mean(),2); }
00111                 
00112                 return mom2-pow(mean(),2);
00113         }
00114         double evallog ( const vec &val ) const {
00115                 int i;
00116                 double sum = 0.0;
00117                 for ( i = 0;i < w.length();i++ ) {sum += w ( i ) * exp ( Coms ( i )->evallog ( val ) );}
00118                 if (sum==0.0){sum=std::numeric_limits<double>::epsilon();}
00119                 double tmp=log ( sum );
00120                 it_assert_debug(std::isfinite(tmp),"Infinite");
00121                 return tmp;
00122         };
00123         vec evallog_m ( const mat &Val ) const {
00124                 vec x=zeros ( Val.cols() );
00125                 for ( int i = 0; i < w.length(); i++ ) {
00126                         x+= w ( i ) *exp ( Coms ( i )->evallog_m ( Val ) );
00127                 }
00128                 return log ( x );
00129         };
00131         mat evallog_M ( const mat &Val ) const {
00132                 mat X ( w.length(), Val.cols() );
00133                 for ( int i = 0; i < w.length(); i++ ) {
00134                         X.set_row ( i, w ( i ) *exp ( Coms ( i )->evallog_m ( Val ) ) );
00135                 }
00136                 return X;
00137         };
00138 
00139         emix* marginal ( const RV &rv ) const;
00140         mratio* condition ( const RV &rv ) const; 
00141 
00142 
00144         vec& _w() {return w;}
00145         virtual ~emix() {if ( destroyComs ) {for ( int i=0;i<Coms.length();i++ ) {delete Coms ( i );}}}
00147         void ownComs() {destroyComs=true;}
00148 
00150         epdf* _Coms ( int i ) {return Coms ( i );}
00151 };
00152 
00161 class mprod: public compositepdf, public mpdf {
00162 protected:
00164         Array<epdf*> epdfs;
00166         Array<datalink_m2m*> dls;
00167 public:
00170         mprod ( Array<mpdf*> mFacs ) : compositepdf ( mFacs ), mpdf ( getrv ( true ),RV() ), epdfs ( n ), dls ( n ) {
00171                 setrvc ( rv,rvc );
00172                 
00173                 for ( int i = 0;i < n;i++ ) {
00174                         dls ( i ) = new datalink_m2m ( mpdfs ( i )->_rv(), mpdfs ( i )->_rvc(), rv, rvc );
00175                 }
00176 
00177                 for ( int i=0;i<n;i++ ) {
00178                         epdfs ( i ) =& ( mpdfs ( i )->_epdf() );
00179                 }
00180         };
00181 
00182         double evallogcond ( const vec &val, const vec &cond ) {
00183                 int i;
00184                 double res = 1.0;
00185                 for ( i = n - 1;i >= 0;i-- ) {
00186                         
00187 
00188 
00189 
00190 
00191                         res *= mpdfs ( i )->evallogcond (
00192                                    dls ( i )->get_val ( val ),
00193                                    dls ( i )->get_cond ( val, cond )
00194                                );
00195                 }
00196                 return res;
00197         }
00198         vec samplecond ( const vec &cond, double &ll ) {
00200                 vec smp= std::numeric_limits<double>::infinity() * ones ( rv.count() );
00201                 vec smpi;
00202                 ll = 0;
00203                 
00204                 for ( int i = ( n - 1 );i >= 0;i-- ) {
00205                         if ( mpdfs ( i )->_rvc().count() ) {
00206                                 mpdfs ( i )->condition ( dls ( i )->get_cond ( smp ,cond ) ); 
00207                         }
00208                         smpi = epdfs ( i )->sample();
00209                         
00210                         dls ( i )->fill_val ( smp, smpi );
00211                         
00212                         ll+=epdfs ( i )->evallog ( smpi );
00213                 }
00214                 return smp;
00215         }
00216         mat samplecond ( const vec &cond, vec &ll, int N ) {
00217                 mat Smp ( rv.count(),N );
00218                 for ( int i=0;i<N;i++ ) {Smp.set_col ( i,samplecond ( cond,ll ( i ) ) );}
00219                 return Smp;
00220         }
00221 
00222         ~mprod() {};
00223 };
00224 
00226 class eprod: public epdf {
00227 protected:
00229         Array<const epdf*> epdfs;
00231         Array<datalink_e2e*> dls;
00232 public:
00233         eprod ( const Array<const epdf*> epdfs0 ) : epdf ( RV() ),epdfs ( epdfs0 ),dls ( epdfs.length() ) {
00234                 bool independent=true;
00235                 for ( int i=0;i<epdfs.length();i++ ) {
00236                         independent=rv.add ( epdfs ( i )->_rv() );
00237                         it_assert_debug ( independent==true, "eprod:: given components are not independent ." );
00238                 }
00239                 for ( int i=0;i<epdfs.length();i++ ) {
00240                         dls ( i ) = new datalink_e2e ( epdfs ( i )->_rv() , rv );
00241                 }
00242         }
00243 
00244         vec mean() const {
00245                 vec tmp ( rv.count() );
00246                 for ( int i=0;i<epdfs.length();i++ ) {
00247                         vec pom = epdfs ( i )->mean();
00248                         dls ( i )->fill_val ( tmp, pom );
00249                 }
00250                 return tmp;
00251         }
00252         vec variance() const {
00253                 vec tmp ( rv.count() ); 
00254                 for ( int i=0;i<epdfs.length();i++ ) {
00255                         vec pom = epdfs ( i )->mean();
00256                         dls ( i )->fill_val ( tmp, pow(pom,2) );
00257                 }
00258                 return tmp-pow(mean(),2);
00259         }
00260         vec sample() const {
00261                 vec tmp ( rv.count() );
00262                 for ( int i=0;i<epdfs.length();i++ ) {
00263                         vec pom = epdfs ( i )->sample();
00264                         dls ( i )->fill_val ( tmp, pom );
00265                 }
00266                 return tmp;
00267         }
00268         double evallog ( const vec &val ) const {
00269                 double tmp=0;
00270                 for ( int i=0;i<epdfs.length();i++ ) {
00271                         tmp+=epdfs ( i )->evallog ( dls ( i )->get_val ( val ) );
00272                 }
00273                 it_assert_debug(std::isfinite(tmp),"Infinite");
00274                 return tmp;
00275         }
00277         const epdf* operator () ( int i ) const {it_assert_debug ( i<epdfs.length(),"wrong index" );return epdfs ( i );}
00278 
00280         ~eprod() {for ( int i=0;i<epdfs.length();i++ ) {delete dls ( i );}}
00281 };
00282 
00283 
00287 class mmix : public mpdf {
00288 protected:
00290         Array<mpdf*> Coms;
00292         emix Epdf;
00293 public:
00295         mmix ( RV &rv, RV &rvc ) : mpdf ( rv, rvc ), Epdf ( rv ) {ep = &Epdf;};
00297         void set_parameters ( const vec &w, const Array<mpdf*> &Coms ) {
00298                 Array<epdf*> Eps ( Coms.length() );
00299 
00300                 for ( int i = 0;i < Coms.length();i++ ) {
00301                         Eps ( i ) = & ( Coms ( i )->_epdf() );
00302                 }
00303                 Epdf.set_parameters ( w, Eps );
00304         };
00305 
00306         void condition ( const vec &cond ) {
00307                 for ( int i = 0;i < Coms.length();i++ ) {Coms ( i )->condition ( cond );}
00308         };
00309 };
00310 
00311 }
00312 #endif //MX_H