00001 
00013 #ifndef MX_H
00014 #define MX_H
00015 
00016 #include "libBM.h"
00017 #include "libEF.h"
00018 
00019 
00020 using namespace itpp;
00021 
00032 class emix : public epdf {
00033 protected:
00035         vec w;
00037         Array<epdf*> Coms;
00039         bool destroyComs;
00040 public:
00042         emix (const RV &rv ) : epdf ( rv ) {};
00044         void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy=true );
00045 
00046         vec sample() const;
00047         vec mean() const {
00048                 int i; vec mu = zeros ( rv.count() );
00049                 for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); }
00050                 return mu;
00051         }
00052         double evalpdflog ( const vec &val ) const {
00053                 int i;
00054                 double sum = 0.0;
00055                 for ( i = 0;i < w.length();i++ ) {sum += w ( i ) * Coms ( i )->evalpdflog ( val );}
00056                 return log ( sum );
00057         };
00058 
00059 
00061         vec& _w() {return w;}
00062         virtual ~emix(){if (destroyComs){for(int i=0;i<Coms.length();i++){delete Coms(i);}}}
00064         void ownComs(){destroyComs=true;}
00065 };
00066 
00075 class mprod: public compositepdf, public mpdf {
00076 protected:
00078         Array<epdf*> epdfs;
00080         Array<ivec> rvcinds;
00081 public:
00085         mprod ( Array<mpdf*> mFacs): compositepdf(mFacs), mpdf(getrv(true),RV()), epdfs(n), rvcinds(n)
00086         {       setrvc(rv,rvc);
00087                 setrvcinrv(rvc,rvcinds);
00088                 setindices(rv); 
00089         for(int i=0;i<n;i++){epdfs(i)=&(mpdfs(i)->_epdf());}
00090         };
00091 
00092         double evalpdflog ( const vec &val ) const {
00093                 int i;
00094                 double res = 0.0;
00095                 for ( i = n - 1;i > 0;i++ ) {
00096                         if ( rvcinds ( i ).length() > 0 )
00097                                 {mpdfs ( i )->condition ( val ( rvcinds ( i ) ) );}
00098                         
00099                         res += epdfs ( i )->evalpdflog ( val ( rvsinrv ( i ) ) );
00100                 }
00101                 return res;
00102         }
00103         vec samplecond ( const vec &cond, double &ll ) {
00104                 vec smp=zeros ( rv.count() );
00105                 vec condi;
00106                 vec smpi;
00107                 ll = 0;
00108                 for ( int i = ( n - 1 );i >= 0;i-- ) {
00109                         if (( rvcinds ( i ).length() > 0 )||( rvcsinrv ( i ).length() > 0 )) {
00110                                 condi = zeros ( rvcsinrv(i).length() + rvcinds(i).length() );
00111                                 
00112                                 set_subvector ( condi,rvcinds ( i ), cond );
00113                                 
00114                                 set_subvector ( condi,rvinrvcs ( i ), get_vec(smp,rvcsinrv(i)) );
00115 
00116                                 mpdfs ( i )->condition ( condi );
00117                         }
00118                         smpi = epdfs ( i )->sample();
00119                         
00120                         set_subvector ( smp,rvsinrv ( i ), smpi );
00121                         
00122                         ll+=epdfs ( i )->evalpdflog ( smpi );
00123                 }
00124                 return smp;
00125         }
00126         mat samplecond ( const vec &cond, vec &ll, int N ) {
00127                 mat Smp ( rv.count(),N );
00128                 for ( int i=0;i<N;i++ ) {Smp.set_col ( i,samplecond ( cond,ll ( i ) ) );}
00129                 return Smp;
00130         }
00131 
00132         ~mprod() {};
00133 };
00134 
00136 class eprod: public epdf {
00137 protected:
00139         Array<const epdf*> epdfs;
00141         Array<ivec> rvinds;
00142 public:
00143         eprod ( const Array<const epdf*> epdfs0 ) : epdf ( RV() ),epdfs ( epdfs0 ),rvinds ( epdfs.length() ) {
00144                 bool independent=true;
00145                 for ( int i=0;i<epdfs.length();i++ ) {
00146                         independent=rv.add ( epdfs ( i )->_rv() );
00147                         it_assert_debug ( independent==true, "eprod:: given components are not independent ." );
00148                         rvinds ( i ) = ( epdfs ( i )->_rv() ).dataind ( rv );
00149                 }
00150         }
00151 
00152         vec mean() const {
00153                 vec tmp ( rv.count() );
00154                 for ( int i=0;i<epdfs.length();i++ ) {
00155                         vec pom = epdfs ( i )->mean();
00156                         set_subvector ( tmp,rvinds ( i ), pom );
00157                 }
00158                 return tmp;
00159         }
00160         vec sample() const {
00161                 vec tmp ( rv.count() );
00162                 for ( int i=0;i<epdfs.length();i++ ) {
00163                         vec pom = epdfs ( i )->sample();
00164                         set_subvector ( tmp,rvinds ( i ), pom );
00165                 }
00166                 return tmp;
00167         }
00168         double evalpdflog ( const vec &val ) const {
00169                 double tmp=0;
00170                 for ( int i=0;i<epdfs.length();i++ ) {
00171                         tmp+=epdfs(i)->evalpdflog(val(rvinds(i)));
00172                 }
00173                 return tmp;
00174         }
00176         const epdf* operator () (int i) const {it_assert_debug(i<epdfs.length(),"wrong index");return epdfs(i);}
00177 };
00178 
00179 
00183 class mmix : public mpdf {
00184 protected:
00186         Array<mpdf*> Coms;
00188         emix Epdf;
00189 public:
00191         mmix ( RV &rv, RV &rvc ) : mpdf ( rv, rvc ), Epdf ( rv ) {ep = &Epdf;};
00193         void set_parameters ( const vec &w, const Array<mpdf*> &Coms ) {
00194                 Array<epdf*> Eps ( Coms.length() );
00195 
00196                 for ( int i = 0;i < Coms.length();i++ ) {
00197                         Eps ( i ) = & ( Coms ( i )->_epdf() );
00198                 }
00199                 Epdf.set_parameters ( w, Eps );
00200         };
00201 
00202         void condition ( const vec &cond ) {
00203                 for ( int i = 0;i < Coms.length();i++ ) {Coms ( i )->condition ( cond );}
00204         };
00205 };
00206 #endif //MX_H