00001 
00013 #ifndef MER_H
00014 #define MER_H
00015 
00016 
00017 #include "mixef.h"
00018 
00019 namespace bdm
00020 {
00021 using std::string;
00022 
00024 enum MERGER_METHOD {ARITHMETIC = 0, GEOMETRIC = 1, LOGNORMAL = 2};
00025 
00045 class merger_base : public compositepdf, public epdf
00046 {
00047         protected:
00049                 Array<datalink_m2e*> dls;
00051                 Array<RV> rvzs;
00053                 Array<datalink_m2e*> zdls;
00055                 int Ns;
00056 
00058                 MERGER_METHOD METHOD;
00060                 double beta;
00061 
00063                 eEmp eSmp;
00064 
00066                 bool DBG;
00067 
00069                 it_file* dbg;
00070         public:
00073 
00075                 merger_base () : compositepdf() {};
00077                 merger_base (const Array<mpdf*> &S) {set_sources (S);};
00079                 void set_sources (const Array<mpdf*> &Sources) {
00080                         compositepdf::set_elements (Sources);
00081                         
00082                         dls.set_size (Sources.length());
00083                         rvzs.set_size (Sources.length());
00084                         zdls.set_size (Sources.length());
00085 
00086                         rv = getrv ( false);
00087                         RV rvc; setrvc (rv, rvc);  
00088                         
00089                         rv.add (rvc);
00090                         
00091                         dim = rv._dsize();
00092 
00093                         
00094                         RV xytmp;
00095                         for (int i = 0;i < mpdfs.length();i++) {
00096                                 
00097                                 dls (i) = new datalink_m2e;
00098                                 dls (i)->set_connection (mpdfs (i)->_rv(), mpdfs (i)->_rvc(), rv);
00099 
00100                                 
00101                                 xytmp = mpdfs (i)->_rv();
00102                                 xytmp.add (mpdfs (i)->_rvc());
00103                                 
00104                                 rvzs (i) = rv.subt (xytmp);
00105                                 
00106                                 zdls (i) = new datalink_m2e; zdls (i)->set_connection (rvzs (i), xytmp, rv) ;
00107                         };
00108                         
00109                         DBG = false;
00110                         METHOD = LOGNORMAL;
00111                         beta = 2.0;
00112                 }
00114                 void set_debug_file (const string fname) { if (DBG) delete dbg; dbg = new it_file (fname); if (dbg) DBG = true;}
00116                 void set_parameters (double beta0, MERGER_METHOD MTH) {beta = beta0;METHOD = MTH;}
00118                 void set_support(epdf &overall, int N){eSmp.set_statistics(&overall,N);Ns=N;}
00119                 
00121                 virtual ~merger_base() {
00122                         for (int i = 0; i < mpdfs.length(); i++) {
00123                                 delete dls (i);
00124                                 delete zdls (i);
00125                         }
00126                         if (DBG) delete dbg;
00127                 };
00129                 
00132                 
00134                 void merge () {
00135                         if (eSmp._w().length() ==0) {it_error("Empty support points use set_support" );}
00136                         
00137                         bool OK = true;
00138                         for (int i = 0;i < mpdfs.length(); i++) {
00139                                 OK &= (rvzs (i)._dsize() == 0); 
00140                                 OK &= (mpdfs (i)->_rvc()._dsize() == 0); 
00141                         }
00142 
00143                         if (OK) {
00144                                 mat lW = zeros (mpdfs.length(), eSmp._w().length());
00145 
00146                                 vec emptyvec (0);
00147                                 for (int i = 0; i < mpdfs.length(); i++) {
00148                                         for (int j = 0; j < eSmp._w().length(); j++) {
00149                                                 lW (i, j) = mpdfs (i)->evallogcond (eSmp._samples() (j), emptyvec);
00150                                         }
00151                                 }
00152 
00153                                 vec wtmp = exp (merge_points (lW));
00154                                 
00155                                 eSmp._w() = wtmp / sum (wtmp);
00156                         } else {
00157                                 it_error("Sources are not compatible - use merger_mix");
00158                         }
00159                         ;
00160                 };
00161 
00162 
00164                 vec merge_points (mat &lW);
00165                 
00166                 
00169                 vec mean() const {
00170                         const Vec<double> &w = eSmp._w();
00171                         const Array<vec> &S = eSmp._samples();
00172                         vec tmp = zeros (dim);
00173                         for (int i = 0; i < Ns; i++) {
00174                                 tmp += w (i) * S (i);
00175                         }
00176                         return tmp;
00177                 }
00178                 mat covariance() const {
00179                         const vec &w = eSmp._w();
00180                         const Array<vec> &S = eSmp._samples();
00181 
00182                         vec mea = mean();
00183 
00184                         cout << sum (w) << "," << w*w << endl;
00185 
00186                         mat Tmp = zeros (dim, dim);
00187                         for (int i = 0; i < Ns; i++) {
00188                                 Tmp += w (i) * outer_product (S (i), S (i));
00189                         }
00190                         return Tmp -outer_product (mea, mea);
00191                 }
00192                 vec variance() const {
00193                         const vec &w = eSmp._w();
00194                         const Array<vec> &S = eSmp._samples();
00195 
00196                         vec tmp = zeros (dim);
00197                         for (int i = 0; i < Ns; i++) {
00198                                 tmp += w (i) * pow (S (i), 2);
00199                         }
00200                         return tmp -pow (mean(), 2);
00201                 }
00203 
00206 
00208                 eEmp& _Smp() {return eSmp;}
00209                 
00211 };
00212 
00213 class merger_mix : public merger_base
00214 {
00215         protected:
00217                 MixEF Mix;
00219                 int Nc;
00221                 double effss_coef;
00222 
00223         public:
00225                 merger_mix () {};
00226                 merger_mix (const Array<mpdf*> &S) {set_sources(S);};
00228                 void set_sources (const Array<mpdf*> &S) {
00229                         merger_base::set_sources(S);
00230                         
00231                         Ns = 100;
00232                         Nc = 10;
00233                         Mix.set_method (EM);
00234                 }
00236                 void set_parameters (double beta0, int Ns0, int Nc0, double effss_coef0 = 0.5) {
00237                         beta = beta0;
00238                         Ns = Ns0;
00239                         Nc = Nc0;
00240                         effss_coef = effss_coef0;
00241                         eSmp.set_parameters (Ns0, false);
00242                 }
00244                 void init() { 
00245                         Array<vec> Smps (Ns);
00246                         
00247                         for (int i = 0;i < mpdfs.length();i++) {Smps (i) = zeros (0);}
00248                 }
00250                 void merge ();
00251 
00254                 vec sample () const { return Mix.posterior().sample();}
00255                 double evallog (const vec &dt) const {
00256                         vec dtf = ones (dt.length() + 1);
00257                         dtf.set_subvector (0, dt);
00258                         return Mix.logpred (dtf);
00259                 }
00260                 vec mean() const {
00261                         const Vec<double> &w = eSmp._w();
00262                         const Array<vec> &S = eSmp._samples();
00263                         vec tmp = zeros (dim);
00264                         for (int i = 0; i < Ns; i++) {
00265                                 tmp += w (i) * S (i);
00266                         }
00267                         return tmp;
00268                 }
00269                 mat covariance() const {
00270                         const vec &w = eSmp._w();
00271                         const Array<vec> &S = eSmp._samples();
00272 
00273                         vec mea = mean();
00274 
00275                         cout << sum (w) << "," << w*w << endl;
00276 
00277                         mat Tmp = zeros (dim, dim);
00278                         for (int i = 0; i < Ns; i++) {
00279                                 Tmp += w (i) * outer_product (S (i), S (i));
00280                         }
00281                         return Tmp -outer_product (mea, mea);
00282                 }
00283                 vec variance() const {
00284                         const vec &w = eSmp._w();
00285                         const Array<vec> &S = eSmp._samples();
00286 
00287                         vec tmp = zeros (dim);
00288                         for (int i = 0; i < Ns; i++) {
00289                                 tmp += w (i) * pow (S (i), 2);
00290                         }
00291                         return tmp -pow (mean(), 2);
00292                 }
00293 
00295                 MixEF& _Mix() {return Mix;}
00297                 emix* proposal() {emix* tmp = Mix.epredictor(); tmp->set_rv (rv); return tmp;}
00299                 eEmp& _Smp() {return eSmp;}
00300 };
00301 
00302 }
00303 
00304 #endif // MER_H