00001
00013 #ifndef BDMBASE_H
00014 #define BDMBASE_H
00015
00016 #include <map>
00017
00018 #include "../itpp_ext.h"
00019 #include "../bdmroot.h"
00020 #include "../shared_ptr.h"
00021 #include "user_info.h"
00022
00023 using namespace libconfig;
00024 using namespace itpp;
00025 using namespace std;
00026
00027 namespace bdm
00028 {
00029
00030 typedef std::map<string, int> RVmap;
00032 extern ivec RV_SIZES;
00034 extern Array<string> RV_NAMES;
00035
00037 class str
00038 {
00039 public:
00041 ivec ids;
00043 ivec times;
00045 str (ivec ids0, ivec times0) : ids (ids0), times (times0) {
00046 bdm_assert_debug (times0.length() == ids0.length(), "Incompatible input");
00047 };
00048 };
00049
00088 class RV : public root
00089 {
00090 protected:
00092 int dsize;
00094 int len;
00096 ivec ids;
00098 ivec times;
00099
00100 private:
00102 void init (const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times);
00103 int init (const string &name, int size);
00104 public:
00107
00109 RV (const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times) {
00110 init (in_names, in_sizes, in_times);
00111 }
00112
00114 RV (const Array<std::string> &in_names, const ivec &in_sizes) {
00115 init (in_names, in_sizes, zeros_i (in_names.length()));
00116 }
00117
00119 RV (const Array<std::string> &in_names) {
00120 init (in_names, ones_i (in_names.length()), zeros_i (in_names.length()));
00121 }
00122
00124 RV() : dsize (0), len (0), ids (0), times (0) {}
00125
00127 RV (string name, int sz, int tm = 0);
00128
00129
00131
00134
00136 friend std::ostream &operator<< (std::ostream &os, const RV &rv);
00137
00138 int _dsize() const {
00139 return dsize;
00140 }
00141
00143 const ivec& _ids() const { return ids;}
00144
00146 int countsize() const;
00147 ivec cumsizes() const;
00148 int length() const {
00149 return len;
00150 }
00151 int id (int at) const {
00152 return ids (at);
00153 }
00154 int size (int at) const {
00155 return RV_SIZES (ids (at));
00156 }
00157 int time (int at) const {
00158 return times (at);
00159 }
00160 std::string name (int at) const {
00161 return RV_NAMES (ids (at));
00162 }
00163 void set_time (int at, int time0) {
00164 times (at) = time0;
00165 }
00167
00170
00172 ivec findself (const RV &rv2) const;
00174 bool equal (const RV &rv2) const;
00176 bool add (const RV &rv2);
00178 RV subt (const RV &rv2) const;
00180 RV subselect (const ivec &ind) const;
00181
00183 RV operator() (const ivec &ind) const {
00184 return subselect (ind);
00185 }
00186
00188 RV operator() (int di1, int di2) const;
00189
00191 void t (int delta);
00193
00196
00198 str tostr() const;
00201 ivec dataind (const RV &crv) const;
00204 void dataind (const RV &rv2, ivec &selfi, ivec &rv2i) const;
00206 int mint() const {
00207 return min (times);
00208 }
00210
00225 void from_setting (const Setting &set);
00226
00227
00229 static void clear_all();
00230 };
00231 UIREGISTER (RV);
00232 SHAREDPTR (RV);
00233
00235 RV concat (const RV &rv1, const RV &rv2);
00236
00238 extern RV RV0;
00239
00241
00242 class fnc : public root
00243 {
00244 protected:
00246 int dimy;
00247 public:
00249 fnc() {};
00251 virtual vec eval (const vec &cond) {
00252 return vec (0);
00253 };
00254
00256 virtual void condition (const vec &val) {};
00257
00259 int dimension() const {
00260 return dimy;
00261 }
00262 };
00263
00264 class mpdf;
00265
00267
00268 class epdf : public root
00269 {
00270 protected:
00272 int dim;
00274 RV rv;
00275
00276 public:
00288 epdf() : dim (0), rv() {};
00289 epdf (const epdf &e) : dim (e.dim), rv (e.rv) {};
00290 epdf (const RV &rv0) : dim (rv0._dsize()) {
00291 set_rv (rv0);
00292 };
00293 void set_parameters (int dim0) {
00294 dim = dim0;
00295 }
00297
00300
00302 virtual vec sample() const {
00303 bdm_error ("not implemented");
00304 return vec();
00305 }
00306
00308 virtual mat sample_m (int N) const;
00309
00312 virtual double evallog (const vec &val) const {
00313 bdm_error ("not implemented");
00314 return 0.0;
00315 }
00316
00318 virtual vec evallog_m (const mat &Val) const;
00319
00321 virtual vec evallog_m (const Array<vec> &Avec) const;
00322
00324 virtual shared_ptr<mpdf> condition (const RV &rv) const;
00325
00327 virtual shared_ptr<epdf> marginal (const RV &rv) const;
00328
00330 virtual vec mean() const {
00331 bdm_error ("not implemneted");
00332 return vec();
00333 }
00334
00336 virtual vec variance() const {
00337 bdm_error ("not implemneted");
00338 return vec();
00339 }
00340
00342 virtual void qbounds (vec &lb, vec &ub, double percentage = 0.95) const {
00343 vec mea = mean();
00344 vec std = sqrt (variance());
00345 lb = mea - 2 * std;
00346 ub = mea + 2 * std;
00347 };
00349
00355
00357 void set_rv (const RV &rv0) {
00358 rv = rv0;
00359 }
00360
00362 bool isnamed() const {
00363 bool b = (dim == rv._dsize());
00364 return b;
00365 }
00366
00368 const RV& _rv() const {
00369 bdm_assert_debug (isnamed(), "");
00370 return rv;
00371 }
00373
00376
00378 int dimension() const {
00379 return dim;
00380 }
00388 void from_setting (const Setting &set) {
00389 shared_ptr<RV> r = UI::build<RV> ( set, "rv", UI::optional );
00390 if (r) {
00391 set_rv (*r);
00392 }
00393 }
00394
00395 };
00396 SHAREDPTR(epdf);
00397
00399 class mpdf : public root
00400 {
00401 protected:
00403 int dimc;
00405 RV rvc;
00406 private:
00408 epdf* ep;
00409
00410 protected:
00412 void set_ep (epdf &iepdf) {
00413 ep = &iepdf;
00414 }
00416 void set_ep (epdf *iepdfp) {
00417 ep = iepdfp;
00418 }
00419
00420 public:
00423
00424 mpdf() : dimc (0), rvc(), ep (NULL) { }
00425
00426 mpdf (const mpdf &m) : dimc (m.dimc), rvc (m.rvc), ep (m.ep) { }
00428
00431
00433 virtual vec samplecond (const vec &cond) {
00434 bdm_error ("Not implemented");
00435 return vec();
00436 }
00437
00439 virtual mat samplecond_m (const vec &cond, int N);
00440
00442 virtual double evallogcond (const vec &dt, const vec &cond) {
00443 bdm_error ("Not implemented");
00444 return 0.0;
00445 }
00446
00448 virtual vec evallogcond_m (const mat &Dt, const vec &cond) {
00449 vec v(Dt.cols());
00450 for(int i=0;i<Dt.cols();i++){v(i)= evallogcond(Dt.get_col(i),cond);}
00451 return v;
00452 }
00453
00455 virtual vec evallogcond_m (const Array<vec> &Dt, const vec &cond) {
00456 bdm_error ("Not implemented");
00457 return vec();
00458 }
00459
00462
00463 RV _rv() const {
00464 return ep->_rv();
00465 }
00466 RV _rvc() {
00467 return rvc;
00468 }
00469
00470 int dimension() const {
00471 return ep->dimension();
00472 }
00473 int dimensionc() {
00474 return dimc;
00475 }
00476
00486 void from_setting (const Setting &set);
00488
00491 void set_rvc (const RV &rvc0) {
00492 rvc = rvc0;
00493 }
00494 void set_rv (const RV &rv0) {
00495 ep->set_rv (rv0);
00496 }
00497 bool isnamed() {
00498 return (ep->isnamed()) && (dimc == rvc._dsize());
00499 }
00501 };
00502 SHAREDPTR(mpdf);
00503
00505 template <class EPDF>
00506 class mpdf_internal: public mpdf
00507 {
00508 protected :
00510 EPDF iepdf;
00511 public:
00513 mpdf_internal() : mpdf(), iepdf() {set_ep (iepdf);}
00514
00517 virtual void condition (const vec &cond) {
00518 bdm_error ("Not implemented");
00519 }
00520
00522 EPDF& e() {return iepdf;}
00523
00525 vec samplecond (const vec &cond);
00527 double evallogcond (const vec &val, const vec &cond);
00529 virtual vec evallogcond_m (const mat &Dt, const vec &cond);
00531 virtual vec evallogcond_m (const Array<vec> &Dt, const vec &cond);
00533 virtual mat samplecond_m (const vec &cond, int N);
00534 };
00535
00561 class datalink
00562 {
00563 protected:
00565 int downsize;
00566
00568 int upsize;
00569
00571 ivec v2v_up;
00572
00573 public:
00575 datalink() : downsize (0), upsize (0) { }
00576
00578 datalink (const RV &rv, const RV &rv_up) {
00579 set_connection (rv, rv_up);
00580 }
00581
00583 void set_connection (const RV &rv, const RV &rv_up);
00584
00586 void set_connection (int ds, int us, const ivec &upind);
00587
00589 vec pushdown (const vec &val_up) {
00590 bdm_assert_debug (upsize == val_up.length(), "Wrong val_up");
00591 return get_vec (val_up, v2v_up);
00592 }
00593
00595 void pushup (vec &val_up, const vec &val) {
00596 bdm_assert_debug (downsize == val.length(), "Wrong val");
00597 bdm_assert_debug (upsize == val_up.length(), "Wrong val_up");
00598 set_subvector (val_up, v2v_up, val);
00599 }
00600 };
00601
00603 class datalink_m2e: public datalink
00604 {
00605 protected:
00607 int condsize;
00608
00610 ivec v2c_up;
00611
00613 ivec v2c_lo;
00614
00615 public:
00617 datalink_m2e() : condsize (0) { }
00618
00620 void set_connection (const RV &rv, const RV &rvc, const RV &rv_up);
00621
00623 vec get_cond (const vec &val_up);
00624
00626 void pushup_cond (vec &val_up, const vec &val, const vec &cond);
00627 };
00628
00631 class datalink_m2m: public datalink_m2e
00632 {
00633 protected:
00635 ivec c2c_up;
00637 ivec c2c_lo;
00638
00639 public:
00641 datalink_m2m() {};
00643 void set_connection (const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up) {
00644 datalink_m2e::set_connection (rv, rvc, rv_up);
00645
00646 rvc.dataind (rvc_up, c2c_lo, c2c_up);
00647 bdm_assert_debug (c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given");
00648 }
00649
00651 vec get_cond (const vec &val_up, const vec &cond_up) {
00652 vec tmp (condsize);
00653 set_subvector (tmp, v2c_lo, val_up (v2c_up));
00654 set_subvector (tmp, c2c_lo, cond_up (c2c_up));
00655 return tmp;
00656 }
00658
00659 };
00660
00666 class logger : public root
00667 {
00668 protected:
00670 Array<RV> entries;
00672 Array<string> names;
00673 public:
00675 logger() : entries (0), names (0) {}
00676
00679 virtual int add (const RV &rv, string prefix = "") {
00680 int id;
00681 if (rv._dsize() > 0) {
00682 id = entries.length();
00683 names = concat (names, prefix);
00684 entries.set_length (id + 1, true);
00685 entries (id) = rv;
00686 } else {
00687 id = -1;
00688 }
00689 return id;
00690 }
00691
00693 virtual void logit (int id, const vec &v) {bdm_error("Not implemented");};
00695 virtual void logit (int id, const double &d) {bdm_error("Not implemented");};
00696
00698 virtual void step() {bdm_error("Not implemneted");};
00699
00701 virtual void finalize() {};
00702
00704 virtual void init() {};
00705
00706 };
00707
00711 class mepdf : public mpdf
00712 {
00714 shared_ptr<epdf> iepdf;
00715 public:
00717 mepdf() { }
00719 mepdf (shared_ptr<epdf> em) {
00720 iepdf = em;
00721 set_ep (*iepdf.get());
00722 dimc = 0;
00723 }
00724
00726 vec samplecond(const vec &cond){return iepdf->sample();}
00727 double evallogcond(const vec &val, const vec &cond){return iepdf->evallog(val);}
00728
00736 void from_setting (const Setting &set);
00737 };
00738 UIREGISTER (mepdf);
00739 SHAREDPTR (mepdf);
00740
00742 RV get_composite_rv ( const Array<shared_ptr<mpdf> > &mpdfs, bool checkoverlap = false );
00743
00751 class DS : public root
00752 {
00753 protected:
00754 int dtsize;
00755 int utsize;
00757 RV Drv;
00759 RV Urv;
00761 int L_dt, L_ut;
00762 public:
00764 DS() : Drv(), Urv() {};
00765
00767 virtual void getdata (vec &dt) {
00768 bdm_error ("abstract class");
00769 }
00770
00772 virtual void getdata (vec &dt, const ivec &indeces) {
00773 bdm_error ("abstract class");
00774 }
00775
00777 virtual void write (vec &ut) {
00778 bdm_error ("abstract class");
00779 }
00780
00782 virtual void write (vec &ut, const ivec &indeces) {
00783 bdm_error ("abstract class");
00784 }
00785
00787 virtual void step() = 0;
00788
00790 virtual void log_add (logger &L) {
00791 bdm_assert_debug (dtsize == Drv._dsize(), "invalid DS: dtsize different from Drv");
00792 bdm_assert_debug (utsize == Urv._dsize(), "invalid DS: utsize different from Urv");
00793
00794 L_dt = L.add (Drv, "");
00795 L_ut = L.add (Urv, "");
00796 }
00798 virtual void logit (logger &L) {
00799 vec tmp (Drv._dsize() + Urv._dsize());
00800 getdata (tmp);
00801
00802 L.logit (L_dt, tmp.left (Drv._dsize()));
00803
00804 L.logit (L_ut, tmp.mid (Drv._dsize(), Urv._dsize()));
00805 }
00807 virtual RV _drv() const {
00808 return concat (Drv, Urv);
00809 }
00811 const RV& _urv() const {
00812 return Urv;
00813 }
00815 virtual void set_drv (const RV &drv, const RV &urv) {
00816 Drv = drv;
00817 Urv = urv;
00818 }
00819 };
00820
00842 class BM : public root
00843 {
00844 protected:
00846 RV drv;
00848 double ll;
00850 bool evalll;
00851 public:
00854
00855 BM() : ll (0), evalll (true), LIDs (4), LFlags (4) {
00856 LIDs = -1;
00857 LFlags = 0;
00858 LFlags (0) = 1;
00859 };
00860 BM (const BM &B) : drv (B.drv), ll (B.ll), evalll (B.evalll) {}
00863 virtual BM* _copy_() const {
00864 return NULL;
00865 };
00867
00870
00874 virtual void bayes (const vec &dt) = 0;
00876 virtual void bayesB (const mat &Dt);
00879 virtual double logpred (const vec &dt) const {
00880 bdm_error ("Not implemented");
00881 return 0.0;
00882 }
00883
00885 vec logpred_m (const mat &dt) const {
00886 vec tmp (dt.cols());
00887 for (int i = 0; i < dt.cols(); i++) {
00888 tmp (i) = logpred (dt.get_col (i));
00889 }
00890 return tmp;
00891 }
00892
00894 virtual epdf* epredictor() const {
00895 bdm_error ("Not implemented");
00896 return NULL;
00897 };
00899 virtual mpdf* predictor() const {
00900 bdm_error ("Not implemented");
00901 return NULL;
00902 };
00904
00909
00911 RV rvc;
00913 const RV& _rvc() const {
00914 return rvc;
00915 }
00916
00918 virtual void condition (const vec &val) {
00919 bdm_error ("Not implemented!");
00920 }
00921
00923
00924
00927
00928 const RV& _drv() const {
00929 return drv;
00930 }
00931 void set_drv (const RV &rv) {
00932 drv = rv;
00933 }
00934 void set_rv (const RV &rv) {
00935 const_cast<epdf&> (posterior()).set_rv (rv);
00936 }
00937 double _ll() const {
00938 return ll;
00939 }
00940 void set_evalll (bool evl0) {
00941 evalll = evl0;
00942 }
00943 virtual const epdf& posterior() const = 0;
00945
00948
00950 virtual void set_options (const string &opt) {
00951 LFlags (0) = 1;
00952 if (opt.find ("logbounds") != string::npos) {
00953 LFlags (1) = 1;
00954 LFlags (2) = 1;
00955 }
00956 if (opt.find ("logll") != string::npos) {
00957 LFlags (3) = 1;
00958 }
00959 }
00961 ivec LIDs;
00962
00964 ivec LFlags;
00966 virtual void log_add (logger &L, const string &name = "") {
00967
00968 RV r;
00969 if (posterior().isnamed()) {
00970 r = posterior()._rv();
00971 } else {
00972 r = RV ("est", posterior().dimension());
00973 };
00974
00975
00976 if (LFlags (0)) LIDs (0) = L.add (r, name + "mean_");
00977 if (LFlags (1)) LIDs (1) = L.add (r, name + "lb_");
00978 if (LFlags (2)) LIDs (2) = L.add (r, name + "ub_");
00979 if (LFlags (3)) LIDs (3) = L.add (RV ("ll", 1), name);
00980 }
00981 virtual void logit (logger &L) {
00982 L.logit (LIDs (0), posterior().mean());
00983 if (LFlags (1) || LFlags (2)) {
00984 vec ub, lb;
00985 posterior().qbounds (lb, ub);
00986 L.logit (LIDs (1), lb);
00987 L.logit (LIDs (2), ub);
00988 }
00989 if (LFlags (3)) L.logit (LIDs (3), ll);
00990 }
00992 void from_setting (const Setting &set){
00993 shared_ptr<RV> r = UI::build<RV> ( set, "drv", UI::optional );
00994 if (r) {
00995 set_drv (*r);
00996 }
00997 string opt;
00998 if(!UI::get(opt, set, "options", UI::optional)) {
00999 set_options(opt);
01000 }
01001 }
01002
01003 };
01004
01005 typedef Array<shared_ptr<epdf> > epdf_array;
01006
01007 typedef Array<shared_ptr<mpdf> > mpdf_array;
01008
01009 template<class EPDF>
01010 vec mpdf_internal<EPDF>::samplecond (const vec &cond)
01011 {
01012 condition (cond);
01013 vec temp = iepdf.sample();
01014 return temp;
01015 }
01016
01017 template<class EPDF>
01018 mat mpdf_internal<EPDF>::samplecond_m (const vec &cond, int N)
01019 {
01020 condition (cond);
01021 mat temp (dimension(), N);
01022 vec smp (dimension());
01023 for (int i = 0; i < N; i++) {
01024 smp = iepdf.sample();
01025 temp.set_col (i, smp);
01026 }
01027
01028 return temp;
01029 }
01030
01031 template<class EPDF>
01032 double mpdf_internal<EPDF>::evallogcond (const vec &dt, const vec &cond)
01033 {
01034 double tmp;
01035 condition (cond);
01036 tmp = iepdf.evallog (dt);
01037 return tmp;
01038 }
01039
01040 template<class EPDF>
01041 vec mpdf_internal<EPDF>::evallogcond_m (const mat &Dt, const vec &cond)
01042 {
01043 condition (cond);
01044 return iepdf.evallog_m (Dt);
01045 }
01046
01047 template<class EPDF>
01048 vec mpdf_internal<EPDF>::evallogcond_m (const Array<vec> &Dt, const vec &cond)
01049 {
01050 condition (cond);
01051 return iepdf.evallog_m (Dt);
01052 }
01053
01054 };
01055 #endif // BDMBASE_H