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 ) * 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