bdmbase.h
Go to the documentation of this file.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 00030 class str { 00031 public: 00033 ivec ids; 00035 ivec times; 00037 str ( ivec ids0, ivec times0 ) : ids ( ids0 ), times ( times0 ) { 00038 bdm_assert ( times0.length() == ids0.length(), "Incompatible input" ); 00039 }; 00040 }; 00041 00082 class RV : public root { 00083 private: 00084 typedef std::map<string, int> str2int_map; 00085 00087 static ivec SIZES; 00089 static Array<string> NAMES; 00091 const static int BUFFER_STEP; 00093 static str2int_map MAP; 00094 00095 public: 00096 00097 protected: 00099 int dsize; 00101 int len; 00103 ivec ids; 00105 ivec times; 00106 00107 private: 00108 enum enum_dummy {dummy}; 00109 00111 void init( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times ); 00112 00114 int assign_id( const string &name, int size ); 00115 00118 explicit RV ( const ivec &ids0, enum_dummy dum ) : dsize ( 0 ), len ( ids0.length() ), ids ( ids0 ), times ( zeros_i ( ids0.length() ) ) { 00119 dsize = countsize(); 00120 } 00121 public: 00124 00126 RV ( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times ) { 00127 init ( in_names, in_sizes, in_times ); 00128 } 00129 00131 RV ( const Array<std::string> &in_names, const ivec &in_sizes ) { 00132 init ( in_names, in_sizes, zeros_i ( in_names.length() ) ); 00133 } 00134 00136 RV ( const Array<std::string> &in_names ) { 00137 init ( in_names, ones_i ( in_names.length() ), zeros_i ( in_names.length() ) ); 00138 } 00139 00141 RV() : dsize ( 0 ), len ( 0 ), ids ( 0 ), times ( 0 ) {} 00142 00144 RV ( string name, int sz, int tm = 0 ); 00145 00147 RV ( int sz, int tm = 0 ); 00148 00149 // compiler-generated copy constructor is used 00151 00154 00156 friend std::ostream &operator<< ( std::ostream &os, const RV &rv ); 00157 00158 string to_string() const { 00159 ostringstream o; 00160 o << *this; 00161 return o.str(); 00162 } 00163 00165 int _dsize() const { 00166 return dsize; 00167 } 00168 00170 const ivec& _ids() const { 00171 return ids; 00172 } 00173 00175 int countsize() const; 00177 ivec cumsizes() const; 00179 int length() const { 00180 return len; 00181 } 00182 int id ( int at ) const { 00183 return ids ( at ); 00184 } 00185 int size ( int at ) const { 00186 return SIZES ( ids ( at ) ); 00187 } 00188 int time ( int at ) const { 00189 return times ( at ); 00190 } 00191 std::string name ( int at ) const { 00192 return NAMES ( ids ( at ) ); 00193 } 00195 std::string scalarname ( int scalat ) const; 00196 00197 void set_time ( int at, int time0 ) { 00198 times ( at ) = time0; 00199 } 00201 00204 00206 ivec findself ( const RV &rv2 ) const; 00208 ivec findself_ids ( const RV &rv2 ) const; 00210 bool equal ( const RV &rv2 ) const; 00212 bool add ( const RV &rv2 ); 00214 RV subt ( const RV &rv2 ) const; 00216 RV subselect ( const ivec &ind ) const; 00217 00219 RV operator() ( const ivec &ind ) const { 00220 return subselect ( ind ); 00221 } 00222 00224 RV operator() ( int di1, int di2 ) const; 00225 00227 void t_plus ( int delta ); 00229 00232 RV remove_time() const { 00233 return RV ( unique ( ids ), dummy ); 00234 } 00236 RV copy_t ( int dt ) const { 00237 RV tmp = *this; 00238 tmp.t_plus ( dt ); 00239 return tmp; 00240 } 00242 RV expand_delayes() const; 00244 00247 00249 str tostr() const; 00252 ivec dataind ( const RV &crv ) const; 00254 ivec dataind_part ( const RV &crv ) const; 00257 void dataind ( const RV &rv2, ivec &selfi, ivec &rv2i ) const; 00259 int mint() const { 00260 return times.length() > 0 ? min ( times ) : 0; 00261 } 00263 int mint ( const RV &rv ) const { 00264 bvec belong = zeros_b ( len ); 00265 for ( int r = 0; r < rv.length(); r++ ) { 00266 belong = belong | ( ids == rv.id ( r ) ); 00267 } 00268 return times.length() > 0 ? min ( get_from_bvec ( times, belong ) ) : 0; 00269 } 00271 00284 void from_setting ( const Setting &set ); 00285 00286 void to_setting ( Setting &set ) const; 00287 00289 static void clear_all(); 00291 string show_all(); 00292 00293 }; 00294 UIREGISTER ( RV ); 00295 SHAREDPTR ( RV ); 00296 00298 RV concat ( const RV &rv1, const RV &rv2 ); 00299 00300 00301 00308 template<class T> class log_level_intermediate : public log_level_base { 00309 protected: 00311 bitset<32> values; 00312 00314 log_level_intermediate( ) { 00315 int len = names().length(); 00316 ids.set_size( len ); 00317 for( int i = 0; i<len; i++ ) 00318 { 00319 ids(i).set_size ( 1 ); 00320 ids(i) = -1; 00321 } 00322 } 00323 public: 00325 static Array<string> string2Array( const string &input ) 00326 { 00327 string result = input; 00328 string::size_type loc; 00329 while( loc = result.find( ',' ), loc != string::npos ) 00330 result[loc] = ' '; 00331 return Array<string>("{ " + result + " }" ); 00332 } 00333 00335 string store_id_and_give_name( enum T::log_level_enums const log_level_enum, int enum_subindex, int id ) { 00336 if( ids(log_level_enum).length() <= enum_subindex ) 00337 ids(log_level_enum).set_size( enum_subindex+1, true ); 00338 ids(log_level_enum)(enum_subindex) = id; 00339 00340 // here we remove a "log" prefix from name, i.e., for instance it transforms "logevidence" to "evidence" 00341 ostringstream stream; 00342 string name_with_prefix = names()(log_level_enum); 00343 string possible_log_prefix = name_with_prefix.substr(0,3); 00344 if( possible_log_prefix == "log" ) 00345 stream << name_with_prefix.substr(3,name_with_prefix.length()-3); 00346 else 00347 stream << name_with_prefix; 00348 00349 // add number to name only in the case there are more registered vectors with the same log_level_enum 00350 if( ids(log_level_enum).length() > 1 ) 00351 stream << "_" << enum_subindex; 00352 00353 return stream.str(); 00354 } 00355 00357 const Array<string> &names() const 00358 { 00359 return T::log_level_names(); 00360 } 00361 00365 bool operator [] (const enum T::log_level_enums &log_level_enum ) const 00366 { 00367 return values[log_level_enum]; 00368 } 00369 00373 bitset<32>::reference operator [] (const enum T::log_level_enums &log_level_enum ) 00374 { 00375 return values[log_level_enum]; 00376 } 00377 }; 00378 //UIREGISTER IS FORBIDDEN FOR THIS CLASS, AS IT SHOULD BE LOADED ONLY THROUGH THE SPECIALIZED UI::GET(...) METHOD 00379 00380 00386 class logger : public root { 00387 protected: 00389 Array<RV> entries; 00391 Array<string> names; 00393 Config setting_conf; 00395 Array<Setting*> settings; 00396 00400 template<class U> void log_setting ( int id, const U data ) { 00401 UI::save(data, *settings ( id ) ); 00402 } 00403 00407 virtual void log_vector ( int id, const vec &v ) NOT_IMPLEMENTED_VOID; 00408 00412 virtual void log_double ( int id, const double &d ) NOT_IMPLEMENTED_VOID; 00413 00415 template<class T> friend class log_level_template; 00416 public: 00420 const string separator; 00421 00423 logger ( const string separator ) : entries ( 0 ), names ( 0 ), separator ( separator ) {} 00424 00426 ~logger() { 00427 finalize(); 00428 } 00429 00436 template<class T> void add_vector ( log_level_intermediate<T> &log_level, enum T::log_level_enums const log_level_enum, const RV &rv, const string &prefix, int enum_subindex = 0 ) 00437 { 00438 if( !log_level.registered_logger ) 00439 log_level.registered_logger = this; 00440 else 00441 bdm_assert_debug ( log_level.registered_logger == this, "This log_level is already registered to another logger!"); 00442 00443 if ( rv._dsize() == 0 ) 00444 return; 00445 00446 int id = entries.length(); 00447 string adjusted_name = log_level.store_id_and_give_name( log_level_enum, enum_subindex, id ); 00448 00449 names = concat ( names, prefix + separator + adjusted_name ); // diff 00450 entries.set_length ( id + 1, true ); 00451 entries ( id ) = rv; 00452 } 00453 00464 template<class T> void add_setting ( log_level_intermediate<T> &log_level, enum T::log_level_enums const log_level_enum, const string &prefix, int enum_subindex = 0 ) { 00465 if( !log_level.registered_logger ) 00466 log_level.registered_logger = this; 00467 else 00468 bdm_assert_debug ( log_level.registered_logger == this, "This log_level is already registered to another logger!"); 00469 00470 Setting &root = setting_conf.getRoot(); 00471 int id = root.getLength(); //root must be group!! 00472 string adjusted_name = log_level.store_id_and_give_name( log_level_enum, enum_subindex, id ); 00473 settings.set_length ( id + 1, true ); 00474 settings ( id ) = &root.add ( prefix + separator + adjusted_name, Setting::TypeList ); 00475 } 00476 00478 virtual void step() = 0; 00479 00483 virtual void finalize() {}; 00484 00486 virtual void init() {}; 00487 }; 00488 00490 template<class T> class log_level_template : public log_level_intermediate<T> { 00491 public: 00492 00494 void from_setting ( const Setting &element ) 00495 { 00496 string raw_log_level; 00497 UI::get( raw_log_level, element ); 00498 Array<string> loaded_log_level = this->string2Array( raw_log_level ); 00499 00500 this->values.reset(); 00501 00502 for( int i = 0; i < loaded_log_level.length(); i++ ) 00503 for( int j = 0; j < this->names().length(); j++ ) { 00504 if( loaded_log_level(i) == this->names()(j) ) 00505 { 00506 this->values[j] = true; 00507 break; 00508 } 00509 } 00510 } 00511 00513 void to_setting ( Setting &element ) const 00514 { 00515 // HERE WE WANT NOT TO DELETE PREVIOUS DATA STORED BY OTHER LOG_LEVELS, SEE SPECIAL IMPLEMENTATION OF UI::GET(...) FOR THIS CLASS 00516 const char* ch_elem=( const char* ) element; 00517 string string_to_write; 00518 if (ch_elem) 00519 string_to_write=ch_elem; 00520 else 00521 string_to_write=""; 00522 00523 for( unsigned int i = 0; i < this->values.size(); i++ ) 00524 if( this->values[i] ) 00525 { 00526 if( string_to_write.length() > 0 ) 00527 string_to_write = string_to_write + ','; 00528 string_to_write = string_to_write + this->names()(i); 00529 } 00530 00531 element = string_to_write; 00532 } 00533 00537 void store( const enum T::log_level_enums log_level_enum, const vec &vect, int enum_subindex = 0 ) const 00538 { 00539 bdm_assert_debug( this->registered_logger != NULL, "You have to register instance to a logger first! Use root::log_register(...) method."); 00540 bdm_assert_debug( ids( log_level_enum )( enum_subindex ) >= 0, "This particular vector was not added to logger! Use logger::add_vector(...) method."); 00541 this->registered_logger->log_vector( ids( log_level_enum )( enum_subindex ), vect ); 00542 } 00543 00547 void store( const enum T::log_level_enums log_level_enum, const double &dbl, int enum_subindex = 0 ) const 00548 { 00549 bdm_assert_debug( this->registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); 00550 bdm_assert_debug( ids( log_level_enum )( enum_subindex ) >= 0, "This particular double was not added to logger! Use logger::add_vector(...) method."); 00551 this->registered_logger->log_double( ids( log_level_enum )( enum_subindex ), dbl ); 00552 } 00553 00557 template<class U> void store( const enum T::log_level_enums log_level_enum, const U data, int enum_subindex = 0 ) const 00558 { 00559 bdm_assert_debug( this->registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); 00560 bdm_assert_debug( ids( log_level_enum )(enum_subindex ) >= 0, "This particular vector was not added to logger! Use logger::add_setting(...) method."); 00561 this->registered_logger->log_setting( ids( log_level_enum )( enum_subindex ), data); 00562 } 00563 }; 00564 //UIREGISTER IS FORBIDDEN FOR THIS CLASS, AS IT SHOULD BE LOADED ONLY THROUGH THE SPECIALIZED UI::GET(...) METHOD 00565 00566 00582 #define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_intermediate<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_template<classname>::string2Array( #__VA_ARGS__ ); return log_level_names; } 00583 00584 00586 class fnc : public root { 00587 protected: 00589 int dimy; 00591 int dimc; 00592 public: 00594 fnc() {}; 00596 virtual vec eval ( const vec &cond ) { 00597 return vec ( 0 ); 00598 }; 00599 00601 int dimension() const { 00602 return dimy; 00603 } 00605 int dimensionc() const { 00606 return dimc; 00607 } 00608 void from_setting(const Setting &set) { 00609 UI::get(dimy, set, "dim", UI::optional); 00610 UI::get(dimc, set, "dimc", UI::optional); 00611 } 00612 }; 00613 00614 class epdf; 00615 00617 class pdf : public root { 00618 protected: 00620 int dimc; 00621 00623 RV rvc; 00624 00626 int dim; 00627 00629 RV rv; 00630 00631 public: 00634 00635 pdf() : dimc ( 0 ), rvc(), dim ( 0 ), rv() { } 00636 00637 pdf ( const pdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), dim ( m.dim ), rv ( m.rv ) { } 00638 00640 00643 00645 virtual vec samplecond ( const vec &cond ) = 0; 00646 00648 virtual mat samplecond_mat ( const vec &cond, int N ); 00649 00651 virtual double evallogcond ( const vec &yt, const vec &cond ) = 0; 00652 00654 virtual vec evallogcond_mat ( const mat &Yt, const vec &cond ) { 00655 vec v ( Yt.cols() ); 00656 for ( int i = 0; i < Yt.cols(); i++ ) { 00657 v ( i ) = evallogcond ( Yt.get_col ( i ), cond ); 00658 } 00659 return v; 00660 } 00661 00663 virtual vec evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) { 00664 vec v ( Yt.length() ); 00665 for ( int i = 0; i < Yt.length(); i++ ) { 00666 v ( i ) = evallogcond ( Yt( i ), cond ); 00667 } 00668 return v; 00669 } 00670 00673 00674 const RV& _rv() const { 00675 return rv; 00676 } 00677 const RV& _rvc() const { 00678 return rvc; 00679 } 00680 00681 int dimension() const { 00682 return dim; 00683 } 00684 int dimensionc() { 00685 return dimc; 00686 } 00687 00689 void set_dim ( int d ) { 00690 dim = d; 00691 } 00693 void set_dimc ( int d ) { 00694 dimc = d; 00695 } 00696 00707 00708 void from_setting ( const Setting &set ); 00709 00710 void to_setting ( Setting &set ) const; 00712 00715 void set_rvc ( const RV &rvc0 ) { 00716 rvc = rvc0; 00717 } 00718 void set_rv ( const RV &rv0 ) { 00719 rv = rv0; 00720 } 00721 00723 bool isnamed() const { 00724 return ( dim == rv._dsize() ) && ( dimc == rvc._dsize() ); 00725 } 00727 }; 00728 SHAREDPTR ( pdf ); 00729 00731 class epdf : public pdf { 00734 00737 00740 00741 LOG_LEVEL(epdf,logmean,loglbound,logubound); 00742 00743 public: 00756 epdf() {}; 00757 epdf ( const epdf &e ) : pdf ( e ) {}; 00758 00759 00761 00764 00766 virtual vec sample() const = 0; 00767 00769 virtual mat sample_mat ( int N ) const; 00770 00773 virtual double evallog ( const vec &val ) const = 0; 00774 00776 virtual vec evallog_mat ( const mat &Val ) const; 00777 00779 virtual vec evallog_mat ( const Array<vec> &Avec ) const; 00780 00782 virtual shared_ptr<pdf> condition ( const RV &rv ) const; 00783 00785 virtual shared_ptr<epdf> marginal ( const RV &rv ) const; 00786 00787 virtual vec mean() const = 0; 00788 00790 virtual vec variance() const = 0; 00791 00793 virtual mat covariance() const { 00794 return diag(variance()); 00795 }; 00796 00798 virtual void qbounds ( vec &lb, vec &ub, double percentage = 0.95 ) const { 00799 vec mea = mean(); 00800 vec std = sqrt ( variance() ); 00801 lb = mea - 2 * std; 00802 ub = mea + 2 * std; 00803 }; 00806 void set_statistics(const epdf *pdf0) NOT_IMPLEMENTED_VOID; 00808 00814 00818 void log_register ( logger &L, const string &prefix ); 00819 00820 void log_write() const; 00822 00833 void from_setting ( const Setting &set ); 00834 void to_setting ( Setting &set ) const; 00835 00836 vec samplecond ( const vec &cond ) { 00837 return sample(); 00838 } 00839 double evallogcond ( const vec &val, const vec &cond ) { 00840 return evallog ( val ); 00841 } 00842 }; 00843 SHAREDPTR ( epdf ); 00844 00846 template <class EPDF> 00847 class pdf_internal: public pdf { 00848 protected : 00850 EPDF iepdf; 00851 public: 00853 pdf_internal() : pdf(), iepdf() { 00854 } 00855 00858 virtual void condition ( const vec &cond ) = 0; 00859 00861 EPDF& e() { 00862 return iepdf; 00863 } 00864 00866 vec samplecond ( const vec &cond ); 00868 double evallogcond ( const vec &val, const vec &cond ); 00870 virtual vec evallogcond_mat ( const mat &Dt, const vec &cond ); 00872 virtual vec evallogcond_mat ( const Array<vec> &Dt, const vec &cond ); 00874 virtual mat samplecond_mat ( const vec &cond, int N ); 00875 00876 void validate() { 00877 pdf::validate(); 00878 iepdf.validate(); 00879 if ( rv._dsize() < iepdf._rv()._dsize() ) { 00880 rv = iepdf._rv(); 00881 }; 00882 dim = iepdf.dimension(); 00883 } 00884 }; 00885 00911 class datalink { 00912 protected: 00914 int downsize; 00915 00917 int upsize; 00918 00920 ivec v2v_up; 00921 00922 public: 00924 datalink() : downsize ( 0 ), upsize ( 0 ) { } 00925 00927 datalink ( const RV &rv, const RV &rv_up ) { 00928 set_connection ( rv, rv_up ); 00929 } 00930 00932 virtual void set_connection ( const RV &rv, const RV &rv_up ); 00933 00935 virtual void set_connection ( int ds, int us, const ivec &upind ); 00936 00938 vec pushdown ( const vec &val_up ) { 00939 vec tmp ( downsize ); 00940 filldown ( val_up, tmp ); 00941 return tmp; 00942 } 00944 virtual void filldown ( const vec &val_up, vec &val_down ) { 00945 bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); 00946 val_down = val_up ( v2v_up ); 00947 } 00949 virtual void pushup ( vec &val_up, const vec &val ) { 00950 bdm_assert_debug ( downsize == val.length(), "Wrong val" ); 00951 bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); 00952 set_subvector ( val_up, v2v_up, val ); 00953 } 00955 int _upsize() { 00956 return upsize; 00957 } 00959 int _downsize() { 00960 return downsize; 00961 } 00963 virtual ~datalink() {} 00964 }; 00965 00968 class datalink_part : public datalink { 00969 protected: 00971 ivec v2v_down; 00972 public: 00973 void set_connection ( const RV &rv, const RV &rv_up ); 00975 void filldown ( const vec &val_up, vec &val_down ) { 00976 set_subvector ( val_down, v2v_down, val_up ( v2v_up ) ); 00977 } 00978 }; 00979 00984 class datalink_buffered: public datalink_part { 00985 protected: 00987 vec history; 00989 RV Hrv; 00991 ivec h2v_down; 00993 ivec h2v_hist; 00995 ivec v2h_up; 00996 public: 00997 00998 datalink_buffered() : datalink_part(), history ( 0 ), h2v_down ( 0 ), h2v_hist ( 0 ) {}; 01000 void store_data ( const vec &val_up ) { 01001 if ( v2h_up.length() > 0 ) { 01002 history.shift_right ( 0, v2h_up.length() ); 01003 history.set_subvector ( 0, val_up ( v2h_up ) ); 01004 } 01005 } 01007 vec pushdown ( const vec &val_up ) { 01008 vec tmp ( downsize ); 01009 filldown ( val_up, tmp ); 01010 return tmp; 01011 } 01012 01013 void filldown ( const vec &val_up, vec &val_down ) { 01014 bdm_assert_debug ( val_down.length() >= downsize, "short val_down" ); 01015 01016 set_subvector ( val_down, v2v_down, val_up ( v2v_up ) ); // copy direct values 01017 set_subvector ( val_down, h2v_down, history ( h2v_hist ) ); // copy delayed values 01018 } 01019 01020 void set_connection ( const RV &rv, const RV &rv_up ); 01021 01023 void set_history ( const RV& rv1, const vec &hist0 ); 01024 }; 01025 01026 class vec_from_vec: public vec { 01027 protected: 01028 datalink_part dl; 01029 int vecfromlen; 01030 public: 01031 void update(const vec &v1) { 01032 bdm_assert_debug(length()==dl._downsize(),"vec_from_vec incompatible"); 01033 bdm_assert_debug(v1.length()==vecfromlen,"This vec was connected to vec of length "+num2str(vecfromlen)+ 01034 ", but vec of length "+num2str(v1.length())+" was obtained" ); 01035 dl.filldown(v1,*this); 01036 }; 01037 void connect(const RV &vecrv, const RV & vec1) { 01038 01039 bdm_assert(vecrv._dsize()==length(),"Description of this vector, "+ vecrv.to_string() +" does not math it length: " + num2str(length())); 01040 dl.set_connection(vecrv,vec1); 01041 vecfromlen=vec1._dsize(); 01042 bdm_assert(dl._downsize()==length(), "Rv of this vector, "+vecrv.to_string() +" was not found in given rv: "+vec1.to_string()); 01043 }; 01044 void push_to(vec &v_up){ 01045 dl.pushup(*this,v_up); 01046 } 01047 datalink_part& _dl() {return dl;} 01048 }; 01049 01050 class vec_from_2vec: public vec { 01051 protected: 01052 datalink_part dl1; 01053 datalink_part dl2; 01054 public: 01055 void update(const vec &v1, const vec &v2) { 01056 bdm_assert_debug(length()==dl1._downsize()+dl2._downsize(),"vec_from_vec incompatible"); 01057 bdm_assert_debug(v1.length()>=dl1._upsize(),"vec_from_vec incompatible"); 01058 bdm_assert_debug(v2.length()>=dl2._upsize(),"vec_from_vec incompatible"); 01059 dl1.filldown(v1,*this); 01060 dl2.filldown(v2,*this); 01061 }; 01062 void connect(const RV &rv, const RV & rv1, const RV &rv2) { 01063 dl1.set_connection(rv,rv1); 01064 dl2.set_connection(rv,rv2); 01065 set_length(rv._dsize()); 01066 }; 01067 }; 01068 01070 class datalink_2to1_buffered { 01071 protected: 01073 datalink_buffered dl1; 01075 datalink_buffered dl2; 01076 public: 01078 void set_connection ( const RV &rv, const RV &rv_up1, const RV &rv_up2 ) { 01079 dl1.set_connection ( rv, rv_up1 ); 01080 dl2.set_connection ( rv, rv_up2 ); 01081 } 01083 void filldown ( const vec &val1, const vec &val2, vec &val_down ) { 01084 bdm_assert_debug ( val_down.length() >= dl1._downsize() + dl2._downsize(), "short val_down" ); 01085 dl1.filldown ( val1, val_down ); 01086 dl2.filldown ( val2, val_down ); 01087 } 01089 void step ( const vec &dt, const vec &ut ) { 01090 dl1.store_data ( dt ); 01091 dl2.store_data ( ut ); 01092 } 01093 }; 01094 01095 01096 01098 class datalink_m2e: public datalink { 01099 protected: 01101 int condsize; 01102 01104 ivec v2c_up; 01105 01107 ivec v2c_lo; 01108 01109 public: 01111 datalink_m2e() : condsize ( 0 ) { } 01112 01114 void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up ); 01115 01117 vec get_cond ( const vec &val_up ); 01118 01120 void pushup_cond ( vec &val_up, const vec &val, const vec &cond ); 01121 }; 01122 01125 class datalink_m2m: public datalink_m2e { 01126 protected: 01128 ivec c2c_up; 01130 ivec c2c_lo; 01131 01132 public: 01134 datalink_m2m() {}; 01136 void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) { 01137 datalink_m2e::set_connection ( rv, rvc, rv_up ); 01138 //establish c2c connection 01139 rvc.dataind ( rvc_up, c2c_lo, c2c_up ); 01140 // bdm_assert_debug ( c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given" ); 01141 } 01142 01144 vec get_cond ( const vec &val_up, const vec &cond_up ) { 01145 vec tmp ( condsize ); 01146 fill_cond ( val_up, cond_up, tmp ); 01147 return tmp; 01148 } 01150 void fill_cond ( const vec &val_up, const vec &cond_up, vec& cond_out ) { 01151 bdm_assert_debug ( cond_out.length() >= condsize, "dl.fill_cond: cond_out is too small" ); 01152 set_subvector ( cond_out, v2c_lo, val_up ( v2c_up ) ); 01153 set_subvector ( cond_out, c2c_lo, cond_up ( c2c_up ) ); 01154 } 01156 01157 }; 01158 01159 01161 RV get_composite_rv ( const Array<shared_ptr<pdf> > &pdfs, bool checkoverlap = false ); 01162 01178 class DS : public root { 01181 01184 LOG_LEVEL(DS,logdt,logut); 01185 01186 protected: 01188 int dtsize; 01190 int utsize; 01192 RV Drv; 01194 RV Urv; // 01195 public: 01197 vec dt; 01199 vec ut; 01200 01202 DS() : dtsize ( 0 ), utsize ( 0 ), Drv(), Urv() { 01203 log_level[logdt] = true; 01204 log_level[logut] = true; 01205 }; 01206 01208 virtual int max_length() { 01209 return std::numeric_limits< int >::max(); 01210 } 01212 virtual void getdata ( vec &dt_out ) const { 01213 bdm_assert_debug(dtsize==dt.length(),"DS::getdata: dt is not of declared size;"); 01214 dt_out=dt; 01215 }; 01216 01218 virtual void getdata ( vec &dt_out, const ivec &indices ) { 01219 bdm_assert_debug(max(indices)<dt.length(), "DS::getdata: indeces out of bounds"); 01220 dt_out = dt(indices); 01221 }; 01222 01224 virtual void write ( const vec &ut ) NOT_IMPLEMENTED_VOID; 01225 01227 virtual void write ( const vec &ut, const ivec &indices ) NOT_IMPLEMENTED_VOID; 01228 01230 virtual void step() = 0; 01231 01233 virtual void log_register ( logger &L, const string &prefix ); 01235 virtual void log_write ( ) const; 01237 virtual const RV& _drv() const { 01238 return Drv; 01239 } 01241 const RV& _urv() const { 01242 return Urv; 01243 } 01244 01253 void from_setting ( const Setting &set ); 01254 01255 void validate(); 01256 }; 01257 01278 class BM : public root { 01281 01284 01287 01288 LOG_LEVEL(BM,logfull,logevidence,logbounds); 01289 01290 protected: 01292 RV yrv; 01294 int dimy; 01296 RV rvc; 01298 int dimc; 01299 01301 double ll; 01303 bool evalll; 01304 01305 public: 01308 01309 BM() : yrv(), dimy ( 0 ), rvc(), dimc ( 0 ), ll ( 0 ), evalll ( true ) { }; 01310 // BM ( const BM &B ) : yrv ( B.yrv ), dimy(B.dimy), rvc ( B.rvc ),dimc(B.dimc), ll ( B.ll ), evalll ( B.evalll ) {} 01313 virtual BM* _copy() const NOT_IMPLEMENTED(NULL); 01315 01318 01322 virtual void bayes ( const vec &yt, const vec &cond = empty_vec ) =0; 01324 virtual double bayes_batch ( const mat &Dt, const vec &cond = empty_vec ); 01326 virtual double bayes_batch ( const mat &Dt, const mat &Cond ); 01330 virtual double logpred ( const vec &yt, const vec &cond ) const NOT_IMPLEMENTED(0.0); 01331 01333 virtual vec samplepred(const vec &cond=empty_vec) NOT_IMPLEMENTED(empty_vec); 01334 01336 vec logpred_mat ( const mat &Yt, const mat &Cond ) const { 01337 vec tmp ( Yt.cols() ); 01338 for ( int i = 0; i < Yt.cols(); i++ ) { 01339 tmp ( i ) = logpred ( Yt.get_col ( i ), Cond.get_col(i) ); 01340 } 01341 return tmp; 01342 } 01343 01345 virtual epdf* epredictor(const vec &cond=vec()) const NOT_IMPLEMENTED(NULL); 01346 01348 virtual pdf* predictor() const NOT_IMPLEMENTED(NULL); 01349 01351 01352 01356 const RV& _rvc() const { 01357 return rvc; 01358 } 01360 int dimensionc() const { 01361 return dimc; 01362 } 01364 int dimensiony() const { 01365 return dimy; 01366 } 01368 int dimension() const { 01369 return posterior().dimension(); 01370 } 01372 const RV& _rv() const { 01373 return posterior()._rv(); 01374 } 01376 const RV& _yrv() const { 01377 return yrv; 01378 } 01380 void set_yrv ( const RV &rv ) { 01381 yrv = rv; 01382 } 01384 void set_rvc ( const RV &rv ) { 01385 rvc = rv; 01386 } 01388 void set_rv ( const RV &rv ) { 01389 const_cast<epdf&> ( posterior() ).set_rv ( rv ); 01390 } 01392 void set_dim ( int dim ) { 01393 const_cast<epdf&> ( posterior() ).set_dim ( dim ); 01394 } 01396 double _ll() const { 01397 return ll; 01398 } 01400 void set_evalll ( bool evl0 ) { 01401 evalll = evl0; 01402 } 01404 virtual const epdf& posterior() const = 0; 01405 01406 epdf& prior() { 01407 return const_cast<epdf&>(posterior()); 01408 } 01410 virtual void set_prior(const epdf *pdf0) NOT_IMPLEMENTED_VOID; 01411 01413 01416 01421 virtual void log_register ( logger &L, const string &prefix = "" ); 01422 01424 virtual void log_write ( ) const; 01425 01427 01442 void from_setting ( const Setting &set ) { 01443 UI::get(yrv, set, "yrv", UI::optional ); 01444 UI::get(rvc, set, "rvc", UI::optional ); 01445 RV r; 01446 UI::get(r, set, "rv", UI::optional ); 01447 set_rv ( r ); 01448 01449 UI::get ( log_level, set, "log_level", UI::optional ); 01450 } 01451 01452 void to_setting ( Setting &set ) const { 01453 root::to_setting( set ); 01454 UI::save( &yrv, set, "yrv" ); 01455 UI::save( &rvc, set, "rvc" ); 01456 UI::save( &posterior()._rv(), set, "rv" ); 01457 UI::save( log_level, set ); 01458 } 01459 01461 void validate() 01462 { 01463 if ( log_level[logbounds] ) { 01464 const_cast<epdf&> ( posterior() ).log_level[epdf::loglbound] = true; 01465 } else { 01466 const_cast<epdf&> ( posterior() ).log_level[epdf::logmean] = true;; 01467 } 01468 } 01469 }; 01470 01472 typedef Array<shared_ptr<epdf> > epdf_array; 01474 typedef Array<shared_ptr<pdf> > pdf_array; 01475 01476 template<class EPDF> 01477 vec pdf_internal<EPDF>::samplecond ( const vec &cond ) { 01478 condition ( cond ); 01479 vec temp = iepdf.sample(); 01480 return temp; 01481 } 01482 01483 template<class EPDF> 01484 mat pdf_internal<EPDF>::samplecond_mat ( const vec &cond, int N ) { 01485 condition ( cond ); 01486 mat temp ( dimension(), N ); 01487 vec smp ( dimension() ); 01488 for ( int i = 0; i < N; i++ ) { 01489 smp = iepdf.sample(); 01490 temp.set_col ( i, smp ); 01491 } 01492 01493 return temp; 01494 } 01495 01496 template<class EPDF> 01497 double pdf_internal<EPDF>::evallogcond ( const vec &yt, const vec &cond ) { 01498 double tmp; 01499 condition ( cond ); 01500 tmp = iepdf.evallog ( yt ); 01501 return tmp; 01502 } 01503 01504 template<class EPDF> 01505 vec pdf_internal<EPDF>::evallogcond_mat ( const mat &Yt, const vec &cond ) { 01506 condition ( cond ); 01507 return iepdf.evallog_mat ( Yt ); 01508 } 01509 01510 template<class EPDF> 01511 vec pdf_internal<EPDF>::evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) { 01512 condition ( cond ); 01513 return iepdf.evallog_mat ( Yt ); 01514 } 01515 01516 }; //namespace 01517 #endif // BDMBASE_H
Generated on 2 Dec 2013 for mixpp by 1.4.7