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 it_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 int countsize() const;
00144 ivec cumsizes() const;
00145 int length() const {
00146 return len;
00147 }
00148 int id (int at) const {
00149 return ids (at);
00150 }
00151 int size (int at) const {
00152 return RV_SIZES (ids (at));
00153 }
00154 int time (int at) const {
00155 return times (at);
00156 }
00157 std::string name (int at) const {
00158 return RV_NAMES (ids (at));
00159 }
00160 void set_time (int at, int time0) {
00161 times (at) = time0;
00162 }
00164
00167
00169 ivec findself (const RV &rv2) const;
00171 bool equal (const RV &rv2) const;
00173 bool add (const RV &rv2);
00175 RV subt (const RV &rv2) const;
00177 RV subselect (const ivec &ind) const;
00178
00180 RV operator() (const ivec &ind) const {
00181 return subselect (ind);
00182 }
00183
00185 RV operator() (int di1, int di2) const;
00186
00188 void t (int delta);
00190
00193
00195 str tostr() const;
00198 ivec dataind (const RV &crv) const;
00201 void dataind (const RV &rv2, ivec &selfi, ivec &rv2i) const;
00203 int mint() const {
00204 return min (times);
00205 }
00207
00222 void from_setting (const Setting &set);
00223
00224
00226 static void clear_all();
00227 };
00228 UIREGISTER (RV);
00229 SHAREDPTR (RV);
00230
00232 RV concat (const RV &rv1, const RV &rv2);
00233
00235 extern RV RV0;
00236
00238
00239 class fnc : public root
00240 {
00241 protected:
00243 int dimy;
00244 public:
00246 fnc() {};
00248 virtual vec eval (const vec &cond) {
00249 return vec (0);
00250 };
00251
00253 virtual void condition (const vec &val) {};
00254
00256 int dimension() const {
00257 return dimy;
00258 }
00259 };
00260
00261 class mpdf;
00262
00264
00265 class epdf : public root
00266 {
00267 protected:
00269 int dim;
00271 RV rv;
00272
00273 public:
00285 epdf() : dim (0), rv() {};
00286 epdf (const epdf &e) : dim (e.dim), rv (e.rv) {};
00287 epdf (const RV &rv0) : dim (rv0._dsize()) {
00288 set_rv (rv0);
00289 };
00290 void set_parameters (int dim0) {
00291 dim = dim0;
00292 }
00294
00297
00299 virtual vec sample() const {
00300 it_error ("not implemented");
00301 return vec (0);
00302 }
00303
00305 virtual mat sample_m (int N) const;
00306
00309 virtual double evallog (const vec &val) const {
00310 it_error ("not implemented");
00311 return 0.0;
00312 }
00313
00315 virtual vec evallog_m (const mat &Val) const;
00316
00318 virtual vec evallog_m (const Array<vec> &Avec) const;
00319
00321 virtual shared_ptr<mpdf> condition (const RV &rv) const;
00322
00324 virtual shared_ptr<epdf> marginal (const RV &rv) const;
00325
00327 virtual vec mean() const {
00328 it_error ("not implemneted");
00329 return vec (0);
00330 };
00331
00333 virtual vec variance() const {
00334 it_error ("not implemneted");
00335 return vec (0);
00336 };
00338 virtual void qbounds (vec &lb, vec &ub, double percentage = 0.95) const {
00339 vec mea = mean();
00340 vec std = sqrt (variance());
00341 lb = mea - 2 * std;
00342 ub = mea + 2 * std;
00343 };
00345
00351
00353 void set_rv (const RV &rv0) {
00354 rv = rv0;
00355 }
00357 bool isnamed() const {
00358 bool b = (dim == rv._dsize());
00359 return b;
00360 }
00362 const RV& _rv() const {
00363 it_assert_debug (isnamed(), "");
00364 return rv;
00365 }
00367
00370
00372 int dimension() const {
00373 return dim;
00374 }
00382 void from_setting (const Setting &set) {
00383 shared_ptr<RV> r = UI::build<RV> ( set, "rv", UI::optional );
00384 if (r) {
00385 set_rv (*r);
00386 }
00387 }
00388
00389 };
00390 SHAREDPTR(epdf);
00391
00393 class mpdf : public root
00394 {
00395 protected:
00397 int dimc;
00399 RV rvc;
00400 private:
00402 epdf* ep;
00403
00404 protected:
00406 void set_ep (epdf &iepdf) {
00407 ep = &iepdf;
00408 }
00410 void set_ep (epdf *iepdfp) {
00411 ep = iepdfp;
00412 }
00413
00414 public:
00417
00418 mpdf() : dimc (0), rvc(), ep (NULL) { }
00419
00420 mpdf (const mpdf &m) : dimc (m.dimc), rvc (m.rvc), ep (m.ep) { }
00422
00425
00427 virtual vec samplecond (const vec &cond) {it_error ("Not implemented");return vec (0);};
00428
00430 virtual mat samplecond_m (const vec &cond, int N);
00431
00433 virtual double evallogcond (const vec &dt, const vec &cond) {it_error ("Not implemented");return 0.0;}
00434
00436 virtual vec evallogcond_m (const mat &Dt, const vec &cond) {
00437 vec v(Dt.cols());
00438 for(int i=0;i<Dt.cols();i++){v(i)= evallogcond(Dt.get_col(i),cond);}
00439 return v;
00440 }
00441
00443 virtual vec evallogcond_m (const Array<vec> &Dt, const vec &cond) {it_error ("Not implemented");return vec (0);}
00444
00447
00448 RV _rv() const {
00449 return ep->_rv();
00450 }
00451 RV _rvc() {
00452 return rvc;
00453 }
00454
00455 int dimension() const {
00456 return ep->dimension();
00457 }
00458 int dimensionc() {
00459 return dimc;
00460 }
00461
00471 void from_setting (const Setting &set);
00473
00476 void set_rvc (const RV &rvc0) {
00477 rvc = rvc0;
00478 }
00479 void set_rv (const RV &rv0) {
00480 ep->set_rv (rv0);
00481 }
00482 bool isnamed() {
00483 return (ep->isnamed()) && (dimc == rvc._dsize());
00484 }
00486 };
00487 SHAREDPTR(mpdf);
00488
00490 template <class EPDF>
00491 class mpdf_internal: public mpdf
00492 {
00493 protected :
00495 EPDF iepdf;
00496 public:
00498 mpdf_internal() : mpdf(), iepdf() {set_ep (iepdf);}
00501 virtual void condition (const vec &cond) {
00502 it_error ("Not implemented");
00503 };
00505 EPDF& e() {return iepdf;}
00506
00508 vec samplecond (const vec &cond);
00510 double evallogcond (const vec &val, const vec &cond);
00512 virtual vec evallogcond_m (const mat &Dt, const vec &cond);
00514 virtual vec evallogcond_m (const Array<vec> &Dt, const vec &cond);
00516 virtual mat samplecond_m (const vec &cond, int N);
00517 };
00518
00544 class datalink
00545 {
00546 protected:
00548 int downsize;
00549
00551 int upsize;
00552
00554 ivec v2v_up;
00555
00556 public:
00558 datalink() : downsize (0), upsize (0) { }
00560 datalink (const RV &rv, const RV &rv_up) {
00561 set_connection (rv, rv_up);
00562 }
00563
00565 void set_connection (const RV &rv, const RV &rv_up) {
00566 downsize = rv._dsize();
00567 upsize = rv_up._dsize();
00568 v2v_up = rv.dataind (rv_up);
00569
00570 it_assert_debug (v2v_up.length() == downsize, "rv is not fully in rv_up");
00571 }
00572
00574 void set_connection (int ds, int us, const ivec &upind) {
00575 downsize = ds;
00576 upsize = us;
00577 v2v_up = upind;
00578
00579 it_assert_debug (v2v_up.length() == downsize, "rv is not fully in rv_up");
00580 }
00581
00583 vec pushdown (const vec &val_up) {
00584 it_assert_debug (upsize == val_up.length(), "Wrong val_up");
00585 return get_vec (val_up, v2v_up);
00586 }
00587
00589 void pushup (vec &val_up, const vec &val) {
00590 it_assert_debug (downsize == val.length(), "Wrong val");
00591 it_assert_debug (upsize == val_up.length(), "Wrong val_up");
00592 set_subvector (val_up, v2v_up, val);
00593 }
00594 };
00595
00597 class datalink_m2e: public datalink
00598 {
00599 protected:
00601 int condsize;
00602
00604 ivec v2c_up;
00605
00607 ivec v2c_lo;
00608
00609 public:
00611 datalink_m2e() : condsize (0) { }
00613 void set_connection (const RV &rv, const RV &rvc, const RV &rv_up) {
00614 datalink::set_connection (rv, rv_up);
00615 condsize = rvc._dsize();
00616
00617 rvc.dataind (rv_up, v2c_lo, v2c_up);
00618 }
00619
00621 vec get_cond (const vec &val_up) {
00622 vec tmp (condsize);
00623 set_subvector (tmp, v2c_lo, val_up (v2c_up));
00624 return tmp;
00625 }
00627 void pushup_cond (vec &val_up, const vec &val, const vec &cond) {
00628 it_assert_debug (downsize == val.length(), "Wrong val");
00629 it_assert_debug (upsize == val_up.length(), "Wrong val_up");
00630 set_subvector (val_up, v2v_up, val);
00631 set_subvector (val_up, v2c_up, cond);
00632 }
00633 };
00634
00637 class datalink_m2m: public datalink_m2e
00638 {
00639 protected:
00641 ivec c2c_up;
00643 ivec c2c_lo;
00644
00645 public:
00647 datalink_m2m() {};
00649 void set_connection (const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up) {
00650 datalink_m2e::set_connection (rv, rvc, rv_up);
00651
00652 rvc.dataind (rvc_up, c2c_lo, c2c_up);
00653 it_assert_debug (c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given");
00654 }
00655
00657 vec get_cond (const vec &val_up, const vec &cond_up) {
00658 vec tmp (condsize);
00659 set_subvector (tmp, v2c_lo, val_up (v2c_up));
00660 set_subvector (tmp, c2c_lo, cond_up (c2c_up));
00661 return tmp;
00662 }
00664
00665 };
00666
00672 class logger : public root
00673 {
00674 protected:
00676 Array<RV> entries;
00678 Array<string> names;
00679 public:
00681 logger() : entries (0), names (0) {}
00682
00685 virtual int add (const RV &rv, string prefix = "") {
00686 int id;
00687 if (rv._dsize() > 0) {
00688 id = entries.length();
00689 names = concat (names, prefix);
00690 entries.set_length (id + 1, true);
00691 entries (id) = rv;
00692 } else {
00693 id = -1;
00694 }
00695 return id;
00696 }
00697
00699 virtual void logit (int id, const vec &v) = 0;
00701 virtual void logit (int id, const double &d) = 0;
00702
00704 virtual void step() = 0;
00705
00707 virtual void finalize() {};
00708
00710 virtual void init() {};
00711
00712 };
00713
00717 class mepdf : public mpdf
00718 {
00720 shared_ptr<epdf> iepdf;
00721 public:
00723 mepdf() { }
00725 mepdf (shared_ptr<epdf> em) {
00726 iepdf = em;
00727 set_ep (*iepdf.get());
00728 dimc = 0;
00729 }
00730
00732 vec samplecond(const vec &cond){return iepdf->sample();}
00733 double evallogcond(const vec &val, const vec &cond){return iepdf->evallog(val);}
00734
00742 void from_setting (const Setting &set);
00743 };
00744 UIREGISTER (mepdf);
00745 SHAREDPTR (mepdf);
00746
00748 RV get_composite_rv ( const Array<shared_ptr<mpdf> > &mpdfs, bool checkoverlap = false );
00749
00757 class DS : public root
00758 {
00759 protected:
00760 int dtsize;
00761 int utsize;
00763 RV Drv;
00765 RV Urv;
00767 int L_dt, L_ut;
00768 public:
00770 DS() : Drv(), Urv() {};
00772 virtual void getdata (vec &dt) {
00773 it_error ("abstract class");
00774 };
00776 virtual void getdata (vec &dt, const ivec &indeces) {
00777 it_error ("abstract class");
00778 };
00780 virtual void write (vec &ut) {
00781 it_error ("abstract class");
00782 };
00784 virtual void write (vec &ut, const ivec &indeces) {
00785 it_error ("abstract class");
00786 };
00787
00789 virtual void step() = 0;
00790
00792 virtual void log_add (logger &L) {
00793 it_assert_debug (dtsize == Drv._dsize(), "");
00794 it_assert_debug (utsize == Urv._dsize(), "");
00795
00796 L_dt = L.add (Drv, "");
00797 L_ut = L.add (Urv, "");
00798 }
00800 virtual void logit (logger &L) {
00801 vec tmp (Drv._dsize() + Urv._dsize());
00802 getdata (tmp);
00803
00804 L.logit (L_dt, tmp.left (Drv._dsize()));
00805
00806 L.logit (L_ut, tmp.mid (Drv._dsize(), Urv._dsize()));
00807 }
00809 virtual RV _drv() const {
00810 return concat (Drv, Urv);
00811 }
00813 const RV& _urv() const {
00814 return Urv;
00815 }
00817 virtual void set_drv (const RV &drv, const RV &urv) {
00818 Drv = drv;
00819 Urv = urv;
00820 }
00821 };
00822
00844 class BM : public root
00845 {
00846 protected:
00848 RV drv;
00850 double ll;
00852 bool evalll;
00853 public:
00856
00857 BM() : ll (0), evalll (true), LIDs (4), LFlags (4) {
00858 LIDs = -1;
00859 LFlags = 0;
00860 LFlags (0) = 1;
00861 };
00862 BM (const BM &B) : drv (B.drv), ll (B.ll), evalll (B.evalll) {}
00865 virtual BM* _copy_() const {
00866 return NULL;
00867 };
00869
00872
00876 virtual void bayes (const vec &dt) = 0;
00878 virtual void bayesB (const mat &Dt);
00881 virtual double logpred (const vec &dt) const {
00882 it_error ("Not implemented");
00883 return 0.0;
00884 }
00886 vec logpred_m (const mat &dt) const {
00887 vec tmp (dt.cols());
00888 for (int i = 0; i < dt.cols(); i++) {
00889 tmp (i) = logpred (dt.get_col (i));
00890 }
00891 return tmp;
00892 }
00893
00895 virtual epdf* epredictor() const {
00896 it_error ("Not implemented");
00897 return NULL;
00898 };
00900 virtual mpdf* predictor() const {
00901 it_error ("Not implemented");
00902 return NULL;
00903 };
00905
00910
00912 RV rvc;
00914 const RV& _rvc() const {
00915 return rvc;
00916 }
00917
00919 virtual void condition (const vec &val) {
00920 it_error ("Not implemented!");
00921 };
00922
00924
00925
00928
00929 const RV& _drv() const {
00930 return drv;
00931 }
00932 void set_drv (const RV &rv) {
00933 drv = rv;
00934 }
00935 void set_rv (const RV &rv) {
00936 const_cast<epdf&> (posterior()).set_rv (rv);
00937 }
00938 double _ll() const {
00939 return ll;
00940 }
00941 void set_evalll (bool evl0) {
00942 evalll = evl0;
00943 }
00944 virtual const epdf& posterior() const = 0;
00946
00949
00951 virtual void set_options (const string &opt) {
00952 LFlags (0) = 1;
00953 if (opt.find ("logbounds") != string::npos) {
00954 LFlags (1) = 1;
00955 LFlags (2) = 1;
00956 }
00957 if (opt.find ("logll") != string::npos) {
00958 LFlags (3) = 1;
00959 }
00960 }
00962 ivec LIDs;
00963
00965 ivec LFlags;
00967 virtual void log_add (logger &L, const string &name = "") {
00968
00969 RV r;
00970 if (posterior().isnamed()) {
00971 r = posterior()._rv();
00972 } else {
00973 r = RV ("est", posterior().dimension());
00974 };
00975
00976
00977 if (LFlags (0)) LIDs (0) = L.add (r, name + "mean_");
00978 if (LFlags (1)) LIDs (1) = L.add (r, name + "lb_");
00979 if (LFlags (2)) LIDs (2) = L.add (r, name + "ub_");
00980 if (LFlags (3)) LIDs (3) = L.add (RV ("ll", 1), name);
00981 }
00982 virtual void logit (logger &L) {
00983 L.logit (LIDs (0), posterior().mean());
00984 if (LFlags (1) || LFlags (2)) {
00985 vec ub, lb;
00986 posterior().qbounds (lb, ub);
00987 L.logit (LIDs (1), lb);
00988 L.logit (LIDs (2), ub);
00989 }
00990 if (LFlags (3)) L.logit (LIDs (3), ll);
00991 }
00993 };
00994
00995 typedef Array<shared_ptr<epdf> > epdf_array;
00996
00997 typedef Array<shared_ptr<mpdf> > mpdf_array;
00998
00999 template<class EPDF>
01000 vec mpdf_internal<EPDF>::samplecond (const vec &cond)
01001 {
01002 condition (cond);
01003 vec temp = iepdf.sample();
01004 return temp;
01005 }
01006
01007 template<class EPDF>
01008 mat mpdf_internal<EPDF>::samplecond_m (const vec &cond, int N)
01009 {
01010 condition (cond);
01011 mat temp (dimension(), N);
01012 vec smp (dimension());
01013 for (int i = 0; i < N; i++) {
01014 smp = iepdf.sample();
01015 temp.set_col (i, smp);
01016 }
01017
01018 return temp;
01019 }
01020
01021 template<class EPDF>
01022 double mpdf_internal<EPDF>::evallogcond (const vec &dt, const vec &cond)
01023 {
01024 double tmp;
01025 condition (cond);
01026 tmp = iepdf.evallog (dt);
01027
01028 return tmp;
01029 }
01030
01031 template<class EPDF>
01032 vec mpdf_internal<EPDF>::evallogcond_m (const mat &Dt, const vec &cond)
01033 {
01034 condition (cond);
01035 return iepdf.evallog_m (Dt);
01036 }
01037
01038 template<class EPDF>
01039 vec mpdf_internal<EPDF>::evallogcond_m (const Array<vec> &Dt, const vec &cond)
01040 {
01041 condition (cond);
01042 return iepdf.evallog_m (Dt);
01043 }
01044
01045 };
01046 #endif // BDMBASE_H