Changeset 377 for bdm/stat/libBM.h

Show
Ignore:
Timestamp:
06/15/09 18:27:16 (15 years ago)
Author:
mido
Message:

1) globalni prejmenovani Setting &root na Setting &set
2) smazani par zastaralych adresaru
3) oprava warningu v doc\local
4) prejmenovani SettingsResolver? na SettingResolver? a drobne vylepseni funkcnosti
5) odstranena duplikace kodu v user_info.cpp

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • bdm/stat/libBM.h

    r364 r377  
    2525using namespace std; 
    2626 
    27 namespace bdm { 
     27namespace bdm 
     28{ 
    2829 
    2930typedef std::map<string, int> RVmap; 
     
    3233 
    3334//! Structure of RV (used internally), i.e. expanded RVs - TODO tak proc je ve verejnem prostoru jmen? upravit 
    34 class str { 
    35 public: 
    36         //! vector id ids (non-unique!) 
    37         ivec ids; 
    38         //! vector of times 
    39         ivec times; 
    40         //!Default constructor 
    41         str ( ivec ids0, ivec times0 ) :ids ( ids0 ),times ( times0 ) { 
    42                 it_assert_debug ( times0.length() ==ids0.length(),"Incompatible input" ); 
    43         }; 
     35class str 
     36{ 
     37public: 
     38  //! vector id ids (non-unique!) 
     39  ivec ids; 
     40  //! vector of times 
     41  ivec times; 
     42  //!Default constructor 
     43  str(ivec ids0, ivec times0) : ids(ids0), times(times0) { 
     44    it_assert_debug(times0.length() == ids0.length(), "Incompatible input"); 
     45  }; 
    4446}; 
    4547 
     
    8284*/ 
    8385 
    84 class RV :public bdmroot { 
    85 protected: 
    86         //! size of the data vector 
    87         int dsize; 
    88         //! number of individual rvs 
    89         int len; 
    90         //! Vector of unique IDs 
    91         ivec ids; 
    92         //! Vector of shifts from current time 
    93         ivec times; 
     86class RV : public bdmroot 
     87{ 
     88protected: 
     89  //! size of the data vector 
     90  int dsize; 
     91  //! number of individual rvs 
     92  int len; 
     93  //! Vector of unique IDs 
     94  ivec ids; 
     95  //! Vector of shifts from current time 
     96  ivec times; 
    9497 
    9598private: 
    96         //! auxiliary function used in constructor 
    97         void init ( Array<std::string> in_names, ivec in_sizes, ivec in_times ); 
    98         int init ( const  string &name, int size ); 
    99 public: 
    100         //! \name Constructors 
    101         //!@{ 
    102  
    103         //! Full constructor 
    104         RV ( Array<std::string> in_names, ivec in_sizes, ivec in_times ) {init ( in_names,in_sizes,in_times );}; 
    105         //! Constructor with times=0 
    106         RV ( Array<std::string> in_names, ivec in_sizes ) {init ( in_names,in_sizes,zeros_i ( in_names.length() ) );}; 
    107         //! Constructor with sizes=1, times=0 
    108         RV ( Array<std::string> in_names ) {init ( in_names,ones_i ( in_names.length() ),zeros_i ( in_names.length() ) );} 
    109         //! Constructor of empty RV 
    110         RV () :dsize ( 0 ),len ( 0 ),ids ( 0 ),times ( 0 ) {}; 
    111         //! Constructor of a single RV with given id 
    112         RV ( string name, int sz, int tm=0 ); 
    113         //!@} 
    114  
    115         //! \name Access functions 
    116         //!@{ 
    117  
    118         //! Printing output e.g. for debugging. 
    119         friend std::ostream &operator<< ( std::ostream &os, const RV &rv ); 
    120         int _dsize() const {return dsize;} ; 
    121         //! Recount size of the corresponding data vector 
    122         int countsize() const; 
    123         ivec cumsizes() const; 
    124         int length() const {return len;} ; 
    125         int id ( int at ) const{return ids ( at );}; 
    126         int size ( int at ) const {return RV_SIZES ( ids ( at ) );}; 
    127         int time ( int at ) const{return times ( at );}; 
    128         std::string name ( int at ) const {return RV_NAMES ( ids ( at ) );}; 
    129         void set_time ( int at, int time0 ) {times ( at ) =time0;}; 
    130         //!@} 
    131  
    132         //TODO why not inline and later?? 
    133  
    134         //! \name Algebra on Random Variables 
    135         //!@{ 
    136  
    137         //! Find indices of self in another rv, \return ivec of the same size as self. 
    138         ivec findself ( const RV &rv2 ) const; 
    139         //! Compare if \c rv2 is identical to this \c RV 
    140         bool equal ( const RV &rv2 ) const; 
    141         //! Add (concat) another variable to the current one, \return true if all rv2 were added, false if rv2 is in conflict 
    142         bool add ( const RV &rv2 ); 
    143         //! Subtract  another variable from the current one 
    144         RV subt ( const RV &rv2 ) const; 
    145         //! Select only variables at indeces ind 
    146         RV subselect ( const ivec &ind ) const; 
    147         //! Select only variables at indeces ind 
    148         RV operator() ( const ivec &ind ) const {return subselect ( ind );}; 
    149         //! Select from data vector starting at di1 to di2 
    150         RV operator() ( int di1, int di2 ) const { 
    151                 ivec sz=cumsizes(); 
    152                 int i1=0; 
    153                 while ( sz ( i1 ) <di1 ) i1++; 
    154                 int i2=i1; 
    155                 while ( sz ( i2 ) <di2 ) i2++; 
    156                 return subselect ( linspace ( i1,i2 ) ); 
    157         }; 
    158         //! Shift \c time shifted by delta. 
    159         void t ( int delta ); 
    160         //!@} 
    161  
    162         //!\name Relation to vectors 
    163         //!@{ 
    164  
    165         //! generate \c str from rv, by expanding sizes TODO to_string..  
    166         str tostr() const; 
    167         //! when this rv is a part of bigger rv, this function returns indeces of self in the data vector of the bigger crv. 
    168         //! Then, data can be copied via: data_of_this = cdata(ind); 
    169         ivec dataind ( const RV &crv ) const; 
    170         //! generate mutual indeces when copying data betwenn self and crv. 
    171         //! Data are copied via: data_of_this(selfi) = data_of_rv2(rv2i) 
    172         void dataind ( const RV &rv2, ivec &selfi, ivec &rv2i ) const; 
    173         //! Minimum time-offset 
    174         int mint () const {return min ( times );}; 
    175         //!@} 
    176  
    177         // TODO aktualizovat dle soucasneho UI 
    178         /*! \brief UI for class RV (description of data vectors) 
    179  
    180         \code 
    181         rv = { 
    182                 type = "rv"; //identifier of the description 
    183                 // UNIQUE IDENTIFIER same names = same variable 
    184                 names = ["a", "b", "c", ...];   // which will be used e.g. in loggers  
    185  
    186                 //optional arguments 
    187                 sizes = [1, 2, 3, ...];         // (optional) default = ones() 
    188                 times = [-1, -2, 0, ...];       // time shifts with respect to current time (optional) default = zeros() 
    189         } 
    190         \endcode 
    191         */ 
    192         void from_setting( const Setting &root ); 
    193  
    194         // TODO dodelat void to_setting( Setting &root ) const; 
     99  //! auxiliary function used in constructor 
     100  void init(Array<std::string> in_names, ivec in_sizes, ivec in_times); 
     101  int init(const  string &name, int size); 
     102public: 
     103  //! \name Constructors 
     104  //!@{ 
     105 
     106  //! Full constructor 
     107  RV(Array<std::string> in_names, ivec in_sizes, ivec in_times) {init(in_names, in_sizes, in_times);}; 
     108  //! Constructor with times=0 
     109  RV(Array<std::string> in_names, ivec in_sizes) {init(in_names, in_sizes, zeros_i(in_names.length()));}; 
     110  //! Constructor with sizes=1, times=0 
     111  RV(Array<std::string> in_names) {init(in_names, ones_i(in_names.length()), zeros_i(in_names.length()));} 
     112  //! Constructor of empty RV 
     113  RV() : dsize(0), len(0), ids(0), times(0) {}; 
     114  //! Constructor of a single RV with given id 
     115  RV(string name, int sz, int tm = 0); 
     116  //!@} 
     117 
     118  //! \name Access functions 
     119  //!@{ 
     120 
     121  //! Printing output e.g. for debugging. 
     122  friend std::ostream &operator<< (std::ostream &os, const RV &rv); 
     123  int _dsize() const {return dsize;} ; 
     124  //! Recount size of the corresponding data vector 
     125  int countsize() const; 
     126  ivec cumsizes() const; 
     127  int length() const {return len;} ; 
     128  int id(int at) const {return ids(at);}; 
     129  int size(int at) const {return RV_SIZES(ids(at));}; 
     130  int time(int at) const {return times(at);}; 
     131  std::string name(int at) const {return RV_NAMES(ids(at));}; 
     132  void set_time(int at, int time0) {times(at) = time0;}; 
     133  //!@} 
     134 
     135  //TODO why not inline and later?? 
     136 
     137  //! \name Algebra on Random Variables 
     138  //!@{ 
     139 
     140  //! Find indices of self in another rv, \return ivec of the same size as self. 
     141  ivec findself(const RV &rv2) const; 
     142  //! Compare if \c rv2 is identical to this \c RV 
     143  bool equal(const RV &rv2) const; 
     144  //! Add (concat) another variable to the current one, \return true if all rv2 were added, false if rv2 is in conflict 
     145  bool add(const RV &rv2); 
     146  //! Subtract  another variable from the current one 
     147  RV subt(const RV &rv2) const; 
     148  //! Select only variables at indeces ind 
     149  RV subselect(const ivec &ind) const; 
     150  //! Select only variables at indeces ind 
     151  RV operator()(const ivec &ind) const {return subselect(ind);}; 
     152  //! Select from data vector starting at di1 to di2 
     153  RV operator()(int di1, int di2) const { 
     154    ivec sz = cumsizes(); 
     155    int i1 = 0; 
     156    while (sz(i1) < di1) i1++; 
     157    int i2 = i1; 
     158    while (sz(i2) < di2) i2++; 
     159    return subselect(linspace(i1, i2)); 
     160  }; 
     161  //! Shift \c time shifted by delta. 
     162  void t(int delta); 
     163  //!@} 
     164 
     165  //!\name Relation to vectors 
     166  //!@{ 
     167 
     168  //! generate \c str from rv, by expanding sizes TODO to_string.. 
     169  str tostr() const; 
     170  //! when this rv is a part of bigger rv, this function returns indeces of self in the data vector of the bigger crv. 
     171  //! Then, data can be copied via: data_of_this = cdata(ind); 
     172  ivec dataind(const RV &crv) const; 
     173  //! generate mutual indeces when copying data betwenn self and crv. 
     174  //! Data are copied via: data_of_this(selfi) = data_of_rv2(rv2i) 
     175  void dataind(const RV &rv2, ivec &selfi, ivec &rv2i) const; 
     176  //! Minimum time-offset 
     177  int mint() const {return min(times);}; 
     178  //!@} 
     179 
     180  // TODO aktualizovat dle soucasneho UI 
     181  /*! \brief UI for class RV (description of data vectors) 
     182 
     183  \code 
     184  rv = { 
     185    type = "rv"; //identifier of the description 
     186    // UNIQUE IDENTIFIER same names = same variable 
     187    names = ["a", "b", "c", ...];   // which will be used e.g. in loggers 
     188 
     189    //optional arguments 
     190    sizes = [1, 2, 3, ...];         // (optional) default = ones() 
     191    times = [-1, -2, 0, ...];       // time shifts with respect to current time (optional) default = zeros() 
     192  } 
     193  \endcode 
     194  */ 
     195  void from_setting(const Setting &set); 
     196 
     197  // TODO dodelat void to_setting( Setting &set ) const; 
    195198}; 
    196199UIREGISTER(RV); 
    197200 
    198201//! Concat two random variables 
    199 RV concat ( const RV &rv1, const RV &rv2 ); 
     202RV concat(const RV &rv1, const RV &rv2); 
    200203 
    201204//!Default empty RV that can be used as default argument 
     
    204207//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv 
    205208 
    206 class fnc :public bdmroot { 
    207 protected: 
    208         //! Length of the output vector 
    209         int dimy; 
    210 public: 
    211         //!default constructor 
    212         fnc ( ) {}; 
    213         //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond 
    214         virtual vec eval ( const vec &cond ) { 
    215                 return vec ( 0 ); 
    216         }; 
    217  
    218         //! function substitutes given value into an appropriate position 
    219         virtual void condition ( const vec &val ) {}; 
    220  
    221         //! access function 
    222         int dimension() const{return dimy;} 
     209class fnc : public bdmroot 
     210{ 
     211protected: 
     212  //! Length of the output vector 
     213  int dimy; 
     214public: 
     215  //!default constructor 
     216  fnc() {}; 
     217  //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond 
     218  virtual vec eval(const vec &cond) { 
     219    return vec(0); 
     220  }; 
     221 
     222  //! function substitutes given value into an appropriate position 
     223  virtual void condition(const vec &val) {}; 
     224 
     225  //! access function 
     226  int dimension() const {return dimy;} 
    223227}; 
    224228 
     
    227231//! Probability density function with numerical statistics, e.g. posterior density. 
    228232 
    229 class epdf : public bdmroot { 
    230 protected: 
    231         //! dimension of the random variable 
    232         int dim; 
    233         //! Description of the random variable 
    234         RV rv; 
    235  
    236 public: 
    237         /*! \name Constructors 
    238          Construction of each epdf should support two types of constructors: 
    239         \li empty constructor, 
    240         \li copy constructor, 
    241  
    242         The following constructors should be supported for convenience: 
    243         \li constructor followed by calling \c set_parameters() 
    244         \li constructor accepting random variables calling \c set_rv() 
    245  
    246          All internal data structures are constructed as empty. Their values (including sizes) will be set by method \c set_parameters(). This way references can be initialized in constructors. 
    247         @{*/ 
    248         epdf() :dim ( 0 ),rv ( ) {}; 
    249         epdf ( const epdf &e ) :dim ( e.dim ),rv ( e.rv ) {}; 
    250         epdf ( const RV &rv0 ) {set_rv ( rv0 );}; 
    251         void set_parameters ( int dim0 ) {dim=dim0;} 
    252         //!@} 
    253  
    254         //! \name Matematical Operations 
    255         //!@{ 
    256  
    257         //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$ 
    258         virtual vec sample () const {it_error ( "not implemneted" );return vec ( 0 );}; 
    259         //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$  from density \f$ f_x(rv)\f$ 
    260         virtual mat sample_m ( int N ) const; 
    261         //! Compute log-probability of argument \c val 
    262         virtual double evallog ( const vec &val ) const {it_error ( "not implemneted" );return 0.0;}; 
    263         //! Compute log-probability of multiple values argument \c val 
    264         virtual vec evallog_m ( const mat &Val ) const { 
    265                 vec x ( Val.cols() ); 
    266                 for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evallog ( Val.get_col ( i ) ) ;} 
    267                 return x; 
    268         } 
    269         //! Return conditional density on the given RV, the remaining rvs will be in conditioning 
    270         virtual mpdf* condition ( const RV &rv ) const  {it_warning ( "Not implemented" ); return NULL;} 
    271         //! Return marginal density on the given RV, the remainig rvs are intergrated out 
    272         virtual epdf* marginal ( const RV &rv ) const {it_warning ( "Not implemented" ); return NULL;} 
    273         //! return expected value 
    274         virtual vec mean() const {it_error ( "not implemneted" );return vec ( 0 );}; 
    275         //! return expected variance (not covariance!) 
    276         virtual vec variance() const {it_error ( "not implemneted" );return vec ( 0 );}; 
    277         //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default 
    278         virtual void qbounds ( vec &lb, vec &ub, double percentage=0.95 ) const { 
    279                 vec mea=mean(); vec std=sqrt ( variance() ); 
    280                 lb = mea-2*std; ub=mea+2*std; 
    281         }; 
    282         //!@} 
    283  
    284         //! \name Connection to other classes 
    285         //! Description of the random quantity via attribute \c rv is optional. 
    286         //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization 
    287         //! and \c conditioning \c rv has to be set. NB: 
    288         //! @{ 
    289  
    290         //!Name its rv 
    291         void set_rv ( const RV &rv0 ) {rv = rv0; }//it_assert_debug(isnamed(),""); }; 
    292         //! True if rv is assigned 
    293         bool isnamed() const {bool b= ( dim==rv._dsize() );return b;} 
    294         //! Return name (fails when isnamed is false) 
    295         const RV& _rv() const {it_assert_debug ( isnamed(),"" ); return rv;} 
    296         //!@} 
    297  
    298         //! \name Access to attributes 
    299         //! @{ 
    300  
    301         //! Size of the random variable 
    302         int dimension() const {return dim;} 
    303         //!@} 
     233class epdf : public bdmroot 
     234{ 
     235protected: 
     236  //! dimension of the random variable 
     237  int dim; 
     238  //! Description of the random variable 
     239  RV rv; 
     240 
     241public: 
     242  /*! \name Constructors 
     243   Construction of each epdf should support two types of constructors: 
     244  \li empty constructor, 
     245  \li copy constructor, 
     246 
     247  The following constructors should be supported for convenience: 
     248  \li constructor followed by calling \c set_parameters() 
     249  \li constructor accepting random variables calling \c set_rv() 
     250 
     251   All internal data structures are constructed as empty. Their values (including sizes) will be set by method \c set_parameters(). This way references can be initialized in constructors. 
     252  @{*/ 
     253  epdf() : dim(0), rv() {}; 
     254  epdf(const epdf &e) : dim(e.dim), rv(e.rv) {}; 
     255  epdf(const RV &rv0) {set_rv(rv0);}; 
     256  void set_parameters(int dim0) {dim = dim0;} 
     257  //!@} 
     258 
     259  //! \name Matematical Operations 
     260  //!@{ 
     261 
     262  //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$ 
     263  virtual vec sample() const {it_error("not implemneted"); return vec(0);}; 
     264  //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$  from density \f$ f_x(rv)\f$ 
     265  virtual mat sample_m(int N) const; 
     266  //! Compute log-probability of argument \c val 
     267  virtual double evallog(const vec &val) const {it_error("not implemneted"); return 0.0;}; 
     268  //! Compute log-probability of multiple values argument \c val 
     269  virtual vec evallog_m(const mat &Val) const { 
     270    vec x(Val.cols()); 
     271    for (int i = 0; i < Val.cols(); i++) {x(i) = evallog(Val.get_col(i)) ;} 
     272    return x; 
     273  } 
     274  //! Return conditional density on the given RV, the remaining rvs will be in conditioning 
     275  virtual mpdf* condition(const RV &rv) const  {it_warning("Not implemented"); return NULL;} 
     276 
     277  //! Return marginal density on the given RV, the remainig rvs are intergrated out 
     278  virtual epdf* marginal(const RV &rv) const {it_warning("Not implemented"); return NULL;} 
     279 
     280  //! return expected value 
     281  virtual vec mean() const {it_error("not implemneted"); return vec(0);}; 
     282 
     283  //! return expected variance (not covariance!) 
     284  virtual vec variance() const {it_error("not implemneted"); return vec(0);}; 
     285  //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default 
     286  virtual void qbounds(vec &lb, vec &ub, double percentage = 0.95) const { 
     287    vec mea = mean(); 
     288    vec std = sqrt(variance()); 
     289    lb = mea - 2 * std; 
     290    ub = mea + 2 * std; 
     291  }; 
     292  //!@} 
     293 
     294  //! \name Connection to other classes 
     295  //! Description of the random quantity via attribute \c rv is optional. 
     296  //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization 
     297  //! and \c conditioning \c rv has to be set. NB: 
     298  //! @{ 
     299 
     300  //!Name its rv 
     301  void set_rv(const RV &rv0) {rv = rv0; }   //it_assert_debug(isnamed(),""); }; 
     302  //! True if rv is assigned 
     303  bool isnamed() const {bool b = (dim == rv._dsize()); return b;} 
     304  //! Return name (fails when isnamed is false) 
     305  const RV& _rv() const {it_assert_debug(isnamed(), ""); return rv;} 
     306  //!@} 
     307 
     308  //! \name Access to attributes 
     309  //! @{ 
     310 
     311  //! Size of the random variable 
     312  int dimension() const {return dim;} 
     313  //!@} 
    304314 
    305315}; 
     
    309319//TODO Samplecond can be generalized 
    310320 
    311 class mpdf : public bdmroot { 
    312 protected: 
    313         //!dimension of the condition 
    314         int dimc; 
    315         //! random variable in condition 
    316         RV rvc; 
    317         //! pointer to internal epdf 
    318         epdf* ep; 
    319 public: 
    320         //! \name Constructors 
    321         //! @{ 
    322  
    323         mpdf ( ) :dimc ( 0 ),rvc ( ) {}; 
    324         //! copy constructor does not set pointer \c ep - has to be done in offsprings! 
    325         mpdf ( const mpdf &m ) :dimc ( m.dimc ),rvc ( m.rvc ) {}; 
    326         //!@} 
    327  
    328         //! \name Matematical operations 
    329         //!@{ 
    330  
    331         //! Returns a sample from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv 
    332         virtual vec samplecond ( const vec &cond ) { 
    333                 this->condition ( cond ); 
    334                 vec temp= ep->sample(); 
    335                 return temp; 
    336         }; 
    337         //! Returns \param N samples from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv  
    338         virtual mat samplecond_m ( const vec &cond, int N ) { 
    339                 this->condition ( cond ); 
    340                 mat temp ( ep->dimension(),N ); vec smp ( ep->dimension() ); 
    341                 for ( int i=0;i<N;i++ ) {smp=ep->sample() ;temp.set_col ( i, smp );} 
    342                 return temp; 
    343         }; 
    344         //! Update \c ep so that it represents this mpdf conditioned on \c rvc = cond 
    345         virtual void condition ( const vec &cond ) {it_error ( "Not implemented" );}; 
    346  
    347         //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently. 
    348         virtual double evallogcond ( const vec &dt, const vec &cond ) { 
    349                 double tmp; this->condition ( cond );tmp = ep->evallog ( dt );          it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); return tmp; 
    350         }; 
    351  
    352         //! Matrix version of evallogcond 
    353         virtual vec evallogcond_m ( const mat &Dt, const vec &cond ) {this->condition ( cond );return ep->evallog_m ( Dt );}; 
    354  
    355         //! \name Access to attributes 
    356         //! @{ 
    357  
    358         RV _rv() {return ep->_rv();} 
    359         RV _rvc() {it_assert_debug ( isnamed(),"" ); return rvc;} 
    360         int dimension() {return ep->dimension();} 
    361         int dimensionc() {return dimc;} 
    362         epdf& _epdf() {return *ep;} 
    363         epdf* _e() {return ep;} 
    364         //!@} 
    365  
    366         //! \name Connection to other objects 
    367         //!@{ 
    368         void set_rvc ( const RV &rvc0 ) {rvc=rvc0;} 
    369         void set_rv ( const RV &rv0 ) {ep->set_rv ( rv0 );} 
    370         bool isnamed() {return ( ep->isnamed() ) && ( dimc==rvc._dsize() );} 
    371         //!@} 
     321class mpdf : public bdmroot 
     322{ 
     323protected: 
     324  //!dimension of the condition 
     325  int dimc; 
     326  //! random variable in condition 
     327  RV rvc; 
     328  //! pointer to internal epdf 
     329  epdf* ep; 
     330public: 
     331  //! \name Constructors 
     332  //! @{ 
     333 
     334  mpdf() : dimc(0), rvc() {}; 
     335  //! copy constructor does not set pointer \c ep - has to be done in offsprings! 
     336  mpdf(const mpdf &m) : dimc(m.dimc), rvc(m.rvc) {}; 
     337  //!@} 
     338 
     339  //! \name Matematical operations 
     340  //!@{ 
     341 
     342  //! Returns a sample from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv 
     343  virtual vec samplecond(const vec &cond) { 
     344    this->condition(cond); 
     345    vec temp = ep->sample(); 
     346    return temp; 
     347  }; 
     348  //! Returns \param N samples from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv 
     349  virtual mat samplecond_m(const vec &cond, int N) { 
     350    this->condition(cond); 
     351    mat temp(ep->dimension(), N); 
     352    vec smp(ep->dimension()); 
     353    for (int i = 0; i < N; i++) {smp = ep->sample() ; temp.set_col(i, smp);} 
     354    return temp; 
     355  }; 
     356  //! Update \c ep so that it represents this mpdf conditioned on \c rvc = cond 
     357  virtual void condition(const vec &cond) {it_error("Not implemented");}; 
     358 
     359  //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently. 
     360  virtual double evallogcond(const vec &dt, const vec &cond) { 
     361    double tmp; 
     362    this->condition(cond); 
     363    tmp = ep->evallog(dt); 
     364    it_assert_debug(std::isfinite(tmp), "Infinite value"); 
     365    return tmp; 
     366  }; 
     367 
     368  //! Matrix version of evallogcond 
     369  virtual vec evallogcond_m(const mat &Dt, const vec &cond) {this->condition(cond); return ep->evallog_m(Dt);}; 
     370 
     371  //! \name Access to attributes 
     372  //! @{ 
     373 
     374  RV _rv() {return ep->_rv();} 
     375  RV _rvc() {it_assert_debug(isnamed(), ""); return rvc;} 
     376  int dimension() {return ep->dimension();} 
     377  int dimensionc() {return dimc;} 
     378  epdf& _epdf() {return *ep;} 
     379  epdf* _e() {return ep;} 
     380  //!@} 
     381 
     382  //! \name Connection to other objects 
     383  //!@{ 
     384  void set_rvc(const RV &rvc0) {rvc = rvc0;} 
     385  void set_rv(const RV &rv0) {ep->set_rv(rv0);} 
     386  bool isnamed() {return (ep->isnamed()) && (dimc == rvc._dsize());} 
     387  //!@} 
    372388}; 
    373389 
     
    378394\dot 
    379395digraph datalink { 
    380         node [shape=record]; 
    381         subgraph cluster0 { 
    382                 label = "Up"; 
    383         up [label="<1>|<2>|<3>|<4>|<5>"]; 
    384                 color = "white" 
     396  node [shape=record]; 
     397  subgraph cluster0 { 
     398    label = "Up"; 
     399      up [label="<1>|<2>|<3>|<4>|<5>"]; 
     400    color = "white" 
    385401} 
    386         subgraph cluster1{ 
    387                 label = "Down"; 
    388                 labelloc = b; 
    389         down [label="<1>|<2>|<3>"]; 
    390                 color = "white" 
     402  subgraph cluster1{ 
     403    label = "Down"; 
     404    labelloc = b; 
     405      down [label="<1>|<2>|<3>"]; 
     406    color = "white" 
    391407} 
    392408    up:1 -> down:1; 
     
    397413 
    398414*/ 
    399 class datalink { 
    400 protected: 
    401         //! Remember how long val should be 
    402         int downsize; 
    403         //! Remember how long val of "Up" should be 
    404         int upsize; 
    405         //! val-to-val link, indeces of the upper val 
    406         ivec v2v_up; 
    407 public: 
    408         //! Constructor 
    409         datalink () {}; 
    410         datalink ( const RV &rv, const RV &rv_up ) {set_connection ( rv,rv_up );}; 
    411         //! set connection, rv must be fully present in rv_up 
    412         void set_connection ( const RV &rv, const RV &rv_up ) { 
    413                 downsize = rv._dsize(); 
    414                 upsize = rv_up._dsize(); 
    415                 v2v_up= ( rv.dataind ( rv_up ) ); 
    416  
    417                 it_assert_debug ( v2v_up.length() ==downsize,"rv is not fully in rv_up" ); 
    418         } 
    419         //! set connection using indeces 
    420         void set_connection ( int ds, int us, const ivec &upind ) { 
    421                 downsize = ds; 
    422                 upsize = us; 
    423                 v2v_up= upind; 
    424  
    425                 it_assert_debug ( v2v_up.length() ==downsize,"rv is not fully in rv_up" ); 
    426         } 
    427         //! Get val for myself from val of "Up" 
    428         vec pushdown ( const vec &val_up ) { 
    429                 it_assert_debug ( upsize==val_up.length(),"Wrong val_up" ); 
    430                 return get_vec ( val_up,v2v_up ); 
    431         } 
    432         //! Fill val of "Up" by my pieces 
    433         void pushup ( vec &val_up, const vec &val ) { 
    434                 it_assert_debug ( downsize==val.length(),"Wrong val" ); 
    435                 it_assert_debug ( upsize==val_up.length(),"Wrong val_up" ); 
    436                 set_subvector ( val_up, v2v_up, val ); 
    437         } 
     415class datalink 
     416{ 
     417protected: 
     418  //! Remember how long val should be 
     419  int downsize; 
     420  //! Remember how long val of "Up" should be 
     421  int upsize; 
     422  //! val-to-val link, indeces of the upper val 
     423  ivec v2v_up; 
     424public: 
     425  //! Constructor 
     426  datalink() {}; 
     427  datalink(const RV &rv, const RV &rv_up) {set_connection(rv, rv_up);}; 
     428  //! set connection, rv must be fully present in rv_up 
     429  void set_connection(const RV &rv, const RV &rv_up) { 
     430    downsize = rv._dsize(); 
     431    upsize = rv_up._dsize(); 
     432    v2v_up = (rv.dataind(rv_up)); 
     433 
     434    it_assert_debug(v2v_up.length() == downsize, "rv is not fully in rv_up"); 
     435  } 
     436  //! set connection using indeces 
     437  void set_connection(int ds, int us, const ivec &upind) { 
     438    downsize = ds; 
     439    upsize = us; 
     440    v2v_up = upind; 
     441 
     442    it_assert_debug(v2v_up.length() == downsize, "rv is not fully in rv_up"); 
     443  } 
     444  //! Get val for myself from val of "Up" 
     445  vec pushdown(const vec &val_up) { 
     446    it_assert_debug(upsize == val_up.length(), "Wrong val_up"); 
     447    return get_vec(val_up, v2v_up); 
     448  } 
     449  //! Fill val of "Up" by my pieces 
     450  void pushup(vec &val_up, const vec &val) { 
     451    it_assert_debug(downsize == val.length(), "Wrong val"); 
     452    it_assert_debug(upsize == val_up.length(), "Wrong val_up"); 
     453    set_subvector(val_up, v2v_up, val); 
     454  } 
    438455}; 
    439456 
    440457//! data link between 
    441 class datalink_m2e: public datalink { 
    442 protected: 
    443         //! Remember how long cond should be 
    444         int condsize; 
    445         //!upper_val-to-local_cond link, indeces of the upper val 
    446         ivec v2c_up; 
    447         //!upper_val-to-local_cond link, ideces of the local cond 
    448         ivec v2c_lo; 
    449  
    450 public: 
    451         datalink_m2e() {}; 
    452         //! Constructor 
    453         void set_connection ( const RV &rv,  const RV &rvc, const RV &rv_up ) { 
    454                 datalink::set_connection ( rv,rv_up ); 
    455                 condsize=  rvc._dsize(); 
    456                 //establish v2c connection 
    457                 rvc.dataind ( rv_up, v2c_lo, v2c_up ); 
    458         } 
    459         //!Construct condition 
    460         vec get_cond ( const vec &val_up ) { 
    461                 vec tmp ( condsize ); 
    462                 set_subvector ( tmp,v2c_lo,val_up ( v2c_up ) ); 
    463                 return tmp; 
    464         } 
    465         void pushup_cond ( vec &val_up, const vec &val, const vec &cond ) { 
    466                 it_assert_debug ( downsize==val.length(),"Wrong val" ); 
    467                 it_assert_debug ( upsize==val_up.length(),"Wrong val_up" ); 
    468                 set_subvector ( val_up, v2v_up, val ); 
    469                 set_subvector ( val_up, v2c_up, cond ); 
    470         } 
     458class datalink_m2e: public datalink 
     459{ 
     460protected: 
     461  //! Remember how long cond should be 
     462  int condsize; 
     463  //!upper_val-to-local_cond link, indeces of the upper val 
     464  ivec v2c_up; 
     465  //!upper_val-to-local_cond link, ideces of the local cond 
     466  ivec v2c_lo; 
     467 
     468public: 
     469  datalink_m2e() {}; 
     470  //! Constructor 
     471  void set_connection(const RV &rv,  const RV &rvc, const RV &rv_up) { 
     472    datalink::set_connection(rv, rv_up); 
     473    condsize =  rvc._dsize(); 
     474    //establish v2c connection 
     475    rvc.dataind(rv_up, v2c_lo, v2c_up); 
     476  } 
     477  //!Construct condition 
     478  vec get_cond(const vec &val_up) { 
     479    vec tmp(condsize); 
     480    set_subvector(tmp, v2c_lo, val_up(v2c_up)); 
     481    return tmp; 
     482  } 
     483  void pushup_cond(vec &val_up, const vec &val, const vec &cond) { 
     484    it_assert_debug(downsize == val.length(), "Wrong val"); 
     485    it_assert_debug(upsize == val_up.length(), "Wrong val_up"); 
     486    set_subvector(val_up, v2v_up, val); 
     487    set_subvector(val_up, v2c_up, cond); 
     488  } 
    471489}; 
    472490//!DataLink is a connection between mpdf and its superordinate (Up) 
    473491//! This class links 
    474 class datalink_m2m: public datalink_m2e { 
    475 protected: 
    476         //!cond-to-cond link, indeces of the upper cond 
    477         ivec c2c_up; 
    478         //!cond-to-cond link, indeces of the local cond 
    479         ivec c2c_lo; 
    480 public: 
    481         //! Constructor 
    482         datalink_m2m() {}; 
    483         void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) { 
    484                 datalink_m2e::set_connection ( rv, rvc, rv_up ); 
    485                 //establish c2c connection 
    486                 rvc.dataind ( rvc_up, c2c_lo, c2c_up ); 
    487                 it_assert_debug ( c2c_lo.length() +v2c_lo.length() ==condsize, "cond is not fully given" ); 
    488         } 
    489         //! Get cond for myself from val and cond of "Up" 
    490         vec get_cond ( const vec &val_up, const vec &cond_up ) { 
    491                 vec tmp ( condsize ); 
    492                 set_subvector ( tmp,v2c_lo,val_up ( v2c_up ) ); 
    493                 set_subvector ( tmp,c2c_lo,cond_up ( c2c_up ) ); 
    494                 return tmp; 
    495         } 
    496         //! Fill 
     492class datalink_m2m: public datalink_m2e 
     493{ 
     494protected: 
     495  //!cond-to-cond link, indeces of the upper cond 
     496  ivec c2c_up; 
     497  //!cond-to-cond link, indeces of the local cond 
     498  ivec c2c_lo; 
     499public: 
     500  //! Constructor 
     501  datalink_m2m() {}; 
     502  void set_connection(const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up) { 
     503    datalink_m2e::set_connection(rv, rvc, rv_up); 
     504    //establish c2c connection 
     505    rvc.dataind(rvc_up, c2c_lo, c2c_up); 
     506    it_assert_debug(c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given"); 
     507  } 
     508  //! Get cond for myself from val and cond of "Up" 
     509  vec get_cond(const vec &val_up, const vec &cond_up) { 
     510    vec tmp(condsize); 
     511    set_subvector(tmp, v2c_lo, val_up(v2c_up)); 
     512    set_subvector(tmp, c2c_lo, cond_up(c2c_up)); 
     513    return tmp; 
     514  } 
     515  //! Fill 
    497516 
    498517}; 
     
    503522This class abstracts logging of results from implementation. This class replaces direct logging of results (e.g. to files or to global variables) by calling methods of a logger. Specializations of this abstract class for specific storage method are designed. 
    504523 */ 
    505 class logger : public bdmroot { 
    506 protected: 
    507         //! RVs of all logged variables. 
    508         Array<RV> entries; 
    509         //! Names of logged quantities, e.g. names of algorithm variants 
    510         Array<string> names; 
    511 public: 
    512         //!Default constructor 
    513         logger ( ) : entries ( 0 ),names ( 0 ) {} 
    514  
    515         //! returns an identifier which will be later needed for calling the \c logit() function 
    516         //! For empty RV it returns -1, this entry will be ignored by \c logit(). 
    517         virtual int add ( const RV &rv, string prefix="" ) { 
    518                 int id; 
    519                 if ( rv._dsize() >0 ) { 
    520                         id=entries.length(); 
    521                         names=concat ( names, prefix); // diff 
    522                         entries.set_length ( id+1,true ); 
    523                         entries ( id ) = rv; 
    524                 } 
    525                 else { id =-1;} 
    526                 return id; // identifier of the last entry 
    527         } 
    528  
    529         //! log this vector 
    530         virtual void logit ( int id, const vec &v ) =0; 
    531         //! log this double 
    532         virtual void logit ( int id, const double &d ) =0; 
    533  
    534         //! Shifts storage position for another time step. 
    535         virtual void step() =0; 
    536  
    537         //! Finalize storing information 
    538         virtual void finalize() {}; 
    539  
    540         //! Initialize the storage 
    541         virtual void init() {}; 
     524class logger : public bdmroot 
     525{ 
     526protected: 
     527  //! RVs of all logged variables. 
     528  Array<RV> entries; 
     529  //! Names of logged quantities, e.g. names of algorithm variants 
     530  Array<string> names; 
     531public: 
     532  //!Default constructor 
     533  logger() : entries(0), names(0) {} 
     534 
     535  //! returns an identifier which will be later needed for calling the \c logit() function 
     536  //! For empty RV it returns -1, this entry will be ignored by \c logit(). 
     537  virtual int add(const RV &rv, string prefix = "") { 
     538    int id; 
     539    if (rv._dsize() > 0) { 
     540      id = entries.length(); 
     541      names = concat(names, prefix); // diff 
     542      entries.set_length(id + 1, true); 
     543      entries(id) = rv; 
     544    } 
     545    else { id = -1;} 
     546    return id; // identifier of the last entry 
     547  } 
     548 
     549  //! log this vector 
     550  virtual void logit(int id, const vec &v) = 0; 
     551  //! log this double 
     552  virtual void logit(int id, const double &d) = 0; 
     553 
     554  //! Shifts storage position for another time step. 
     555  virtual void step() = 0; 
     556 
     557  //! Finalize storing information 
     558  virtual void finalize() {}; 
     559 
     560  //! Initialize the storage 
     561  virtual void init() {}; 
    542562 
    543563}; 
     
    546566 
    547567*/ 
    548 class mepdf : public mpdf { 
    549 public: 
    550         //!Default constructor 
    551         mepdf ( epdf* em ) :mpdf ( ) {ep= em ;}; 
    552         mepdf (const epdf* em ) :mpdf ( ) {ep=const_cast<epdf*>( em );}; 
    553         void condition ( const vec &cond ) {} 
     568class mepdf : public mpdf 
     569{ 
     570public: 
     571  //!Default constructor 
     572  mepdf(epdf* em) : mpdf() {ep = em ;}; 
     573  mepdf(const epdf* em) : mpdf() {ep = const_cast<epdf*>(em);}; 
     574  void condition(const vec &cond) {} 
    554575}; 
    555576 
    556577//!\brief Abstract composition of pdfs, will be used for specific classes 
    557578//!this abstract class is common to epdf and mpdf 
    558 class compositepdf { 
    559 protected: 
    560         //!Number of mpdfs in the composite 
    561         int n; 
    562         //! Elements of composition 
    563         Array<mpdf*> mpdfs; 
    564 public: 
    565         compositepdf ( Array<mpdf*> A0 ) : n ( A0.length() ), mpdfs ( A0 ) {}; 
    566         //! find common rv, flag \param checkoverlap modifies whether overlaps are acceptable 
    567         RV getrv ( bool checkoverlap=false ); 
    568         //! common rvc of all mpdfs is written to rvc 
    569         void setrvc ( const RV &rv, RV &rvc ); 
     579class compositepdf 
     580{ 
     581protected: 
     582  //!Number of mpdfs in the composite 
     583  int n; 
     584  //! Elements of composition 
     585  Array<mpdf*> mpdfs; 
     586public: 
     587  compositepdf(Array<mpdf*> A0) : n(A0.length()), mpdfs(A0) {}; 
     588  //! find common rv, flag \param checkoverlap modifies whether overlaps are acceptable 
     589  RV getrv(bool checkoverlap = false); 
     590  //! common rvc of all mpdfs is written to rvc 
     591  void setrvc(const RV &rv, RV &rvc); 
    570592}; 
    571593 
     
    577599*/ 
    578600 
    579 class DS : public bdmroot { 
    580 protected: 
    581         int dtsize; 
    582         int utsize; 
    583         //!Description of data returned by \c getdata(). 
    584         RV Drv; 
    585         //!Description of data witten by by \c write(). 
    586         RV Urv; // 
    587         //! Remember its own index in Logger L 
    588         int L_dt, L_ut; 
    589 public: 
    590         //! default constructors 
    591         DS() :Drv ( ),Urv ( ) {}; 
    592         //! Returns full vector of observed data=[output, input] 
    593         virtual void getdata ( vec &dt ) {it_error ( "abstract class" );}; 
    594         //! Returns data records at indeces. 
    595         virtual void getdata ( vec &dt, const ivec &indeces ) {it_error ( "abstract class" );}; 
    596         //! Accepts action variable and schedule it for application. 
    597         virtual void write ( vec &ut ) {it_error ( "abstract class" );}; 
    598         //! Accepts action variables at specific indeces 
    599         virtual void write ( vec &ut, const ivec &indeces ) {it_error ( "abstract class" );}; 
    600  
    601         //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system. 
    602         virtual void step() =0; 
    603  
    604         //! Register DS for logging into logger L 
    605         virtual void log_add ( logger &L ) { 
    606                 it_assert_debug ( dtsize==Drv._dsize(),"" ); 
    607                 it_assert_debug ( utsize==Urv._dsize(),"" ); 
    608  
    609                 L_dt=L.add ( Drv,"" ); 
    610                 L_ut=L.add ( Urv,"" ); 
    611         } 
    612         //! Register DS for logging into logger L 
    613         virtual void logit ( logger &L ) { 
    614                 vec tmp ( Drv._dsize() +Urv._dsize() ); 
    615                 getdata ( tmp ); 
    616                 // d is first in getdata 
    617                 L.logit ( L_dt,tmp.left ( Drv._dsize() ) ); 
    618                 // u follows after d in getdata 
    619                 L.logit ( L_ut,tmp.mid ( Drv._dsize(), Urv._dsize() ) ); 
    620         } 
    621         //!access function 
    622         virtual RV _drv() const {return concat ( Drv,Urv );} 
    623         //!access function 
    624         const RV& _urv() const {return Urv;} 
    625         //! set random rvariables 
    626         virtual void set_drv (const  RV &drv, const RV &urv) { Drv=drv;Urv=urv;} 
     601class DS : public bdmroot 
     602{ 
     603protected: 
     604  int dtsize; 
     605  int utsize; 
     606  //!Description of data returned by \c getdata(). 
     607  RV Drv; 
     608  //!Description of data witten by by \c write(). 
     609  RV Urv; // 
     610  //! Remember its own index in Logger L 
     611  int L_dt, L_ut; 
     612public: 
     613  //! default constructors 
     614  DS() : Drv(), Urv() {}; 
     615  //! Returns full vector of observed data=[output, input] 
     616  virtual void getdata(vec &dt) {it_error("abstract class");}; 
     617  //! Returns data records at indeces. 
     618  virtual void getdata(vec &dt, const ivec &indeces) {it_error("abstract class");}; 
     619  //! Accepts action variable and schedule it for application. 
     620  virtual void write(vec &ut) {it_error("abstract class");}; 
     621  //! Accepts action variables at specific indeces 
     622  virtual void write(vec &ut, const ivec &indeces) {it_error("abstract class");}; 
     623 
     624  //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system. 
     625  virtual void step() = 0; 
     626 
     627  //! Register DS for logging into logger L 
     628  virtual void log_add(logger &L) { 
     629    it_assert_debug(dtsize == Drv._dsize(), ""); 
     630    it_assert_debug(utsize == Urv._dsize(), ""); 
     631 
     632    L_dt = L.add(Drv, ""); 
     633    L_ut = L.add(Urv, ""); 
     634  } 
     635  //! Register DS for logging into logger L 
     636  virtual void logit(logger &L) { 
     637    vec tmp(Drv._dsize() + Urv._dsize()); 
     638    getdata(tmp); 
     639    // d is first in getdata 
     640    L.logit(L_dt, tmp.left(Drv._dsize())); 
     641    // u follows after d in getdata 
     642    L.logit(L_ut, tmp.mid(Drv._dsize(), Urv._dsize())); 
     643  } 
     644  //!access function 
     645  virtual RV _drv() const {return concat(Drv, Urv);} 
     646  //!access function 
     647  const RV& _urv() const {return Urv;} 
     648  //! set random rvariables 
     649  virtual void set_drv(const  RV &drv, const RV &urv) { Drv = drv; Urv = urv;} 
    627650}; 
    628651 
     
    648671*/ 
    649672 
    650 class BM :public bdmroot { 
    651 protected: 
    652         //! Random variable of the data (optional) 
    653         RV drv; 
    654         //!Logarithm of marginalized data likelihood. 
    655         double ll; 
    656         //!  If true, the filter will compute likelihood of the data record and store it in \c ll . Set to false if you want to save computational time. 
    657         bool evalll; 
    658 public: 
    659         //! \name Constructors 
    660         //! @{ 
    661  
    662         BM () :ll ( 0 ),evalll ( true ), LIDs ( 4 ), LFlags(4) { 
    663                 LIDs=-1;/*empty IDs*/ LFlags=0; LFlags(0)=1;/*log only mean*/}; 
    664         BM ( const BM &B ) :  drv ( B.drv ), ll ( B.ll ), evalll ( B.evalll ) {} 
    665         //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually! 
    666         //! Prototype: \code BM* _copy_() const {return new BM(*this);} \endcode 
    667         virtual BM* _copy_ () const {return NULL;}; 
    668         //!@} 
    669  
    670         //! \name Mathematical operations 
    671         //!@{ 
    672  
    673         /*! \brief Incremental Bayes rule 
    674         @param dt vector of input data 
    675         */ 
    676         virtual void bayes ( const vec &dt ) = 0; 
    677         //! Batch Bayes rule (columns of Dt are observations) 
    678         virtual void bayesB ( const mat &Dt ); 
    679         //! Evaluates predictive log-likelihood of the given data record 
    680         //! I.e. marginal likelihood of the data with the posterior integrated out. 
    681         virtual double logpred ( const vec &dt ) const{it_error ( "Not implemented" );return 0.0;} 
    682         //! Matrix version of logpred 
    683         vec logpred_m ( const mat &dt ) const{vec tmp ( dt.cols() );for ( int i=0;i<dt.cols();i++ ) {tmp ( i ) =logpred ( dt.get_col ( i ) );}return tmp;} 
    684  
    685         //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$ 
    686         virtual epdf* epredictor ( ) const {it_error ( "Not implemented" );return NULL;}; 
    687         //!Constructs a conditional density 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) 
    688         virtual mpdf* predictor ( ) const {it_error ( "Not implemented" );return NULL;}; 
    689         //!@} 
    690  
    691         //! \name Extension to conditional BM 
    692         //! This extension is useful e.g. in Marginalized Particle Filter (\ref bdm::MPF). 
    693         //! Alternatively, it can be used for automated connection to DS when the condition is observed 
    694         //!@{ 
    695  
    696         //! Name of extension variable 
    697         RV rvc; 
    698         //! access function 
    699         const RV& _rvc() const {return rvc;} 
    700  
    701         //! Substitute \c val for \c rvc. 
    702         virtual void condition ( const vec &val ) {it_error ( "Not implemented!" );}; 
    703  
    704         //!@} 
    705  
    706  
    707         //! \name Access to attributes 
    708         //!@{ 
    709  
    710         const RV& _drv() const {return drv;} 
    711         void set_drv ( const RV &rv ) {drv=rv;} 
    712         void set_rv ( const RV &rv ) {const_cast<epdf&> ( posterior() ).set_rv ( rv );} 
    713         double _ll() const {return ll;} 
    714         void set_evalll ( bool evl0 ) {evalll=evl0;} 
    715         virtual const epdf& posterior() const =0; 
    716         virtual const epdf* _e() const =0; 
    717         //!@} 
    718  
    719         //! \name Logging of results 
    720         //!@{ 
    721  
    722         //! Set boolean options from a string recognized are: "logbounds,logll" 
    723         virtual void set_options ( const string &opt ) { 
    724                 LFlags(0)=1; 
    725                 if ( opt.find ( "logbounds" ) !=string::npos ) {LFlags(1)=1; LFlags(2)=1;} 
    726                 if ( opt.find ( "logll" ) !=string::npos ) {LFlags(3)=1;} 
    727         } 
    728         //! IDs of storages in loggers 4:[1=mean,2=lb,3=ub,4=ll] 
    729         ivec LIDs; 
    730  
    731         //! Flags for logging - same size as LIDs, each entry correspond to the same in LIDs 
    732         ivec LFlags; 
    733         //! Add all logged variables to a logger 
    734         virtual void log_add ( logger &L, const string &name="" ) { 
    735                 // internal 
    736                 RV r; 
    737                 if ( posterior().isnamed() ) {r=posterior()._rv();} 
    738                 else{r=RV ( "est", posterior().dimension() );}; 
    739  
    740                 // Add mean value 
    741                 if (LFlags(0)) LIDs ( 0 ) =L.add ( r,name+"mean_" ); 
    742                 if (LFlags(1)) LIDs ( 1 ) =L.add ( r,name+"lb_" ); 
    743                 if (LFlags(2)) LIDs ( 2 ) =L.add ( r,name+"ub_" ); 
    744                 if (LFlags(3)) LIDs ( 3 ) =L.add ( RV("ll",1),name ); //TODO: "local" RV  
    745         } 
    746         virtual void logit ( logger &L ) { 
    747                 L.logit ( LIDs ( 0 ), posterior().mean() ); 
    748                 if ( LFlags(1) || LFlags(2)) { //if one of them is off, its LID==-1 and will not be stored 
    749                         vec ub,lb; 
    750                         posterior().qbounds ( lb,ub ); 
    751                         L.logit ( LIDs ( 1 ), lb );  
    752                         L.logit ( LIDs ( 2 ), ub ); 
    753                 } 
    754                 if (LFlags(3)) L.logit ( LIDs ( 3 ), ll ); 
    755         } 
    756         //!@} 
     673class BM : public bdmroot 
     674{ 
     675protected: 
     676  //! Random variable of the data (optional) 
     677  RV drv; 
     678  //!Logarithm of marginalized data likelihood. 
     679  double ll; 
     680  //!  If true, the filter will compute likelihood of the data record and store it in \c ll . Set to false if you want to save computational time. 
     681  bool evalll; 
     682public: 
     683  //! \name Constructors 
     684  //! @{ 
     685 
     686  BM() : ll(0), evalll(true), LIDs(4), LFlags(4) { 
     687    LIDs = -1;/*empty IDs*/ 
     688    LFlags = 0; 
     689    LFlags(0) = 1;/*log only mean*/ 
     690  }; 
     691  BM(const BM &B) :  drv(B.drv), ll(B.ll), evalll(B.evalll) {} 
     692  //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually! 
     693  //! Prototype: \code BM* _copy_() const {return new BM(*this);} \endcode 
     694  virtual BM* _copy_() const {return NULL;}; 
     695  //!@} 
     696 
     697  //! \name Mathematical operations 
     698  //!@{ 
     699 
     700  /*! \brief Incremental Bayes rule 
     701  @param dt vector of input data 
     702  */ 
     703  virtual void bayes(const vec &dt) = 0; 
     704  //! Batch Bayes rule (columns of Dt are observations) 
     705  virtual void bayesB(const mat &Dt); 
     706  //! Evaluates predictive log-likelihood of the given data record 
     707  //! I.e. marginal likelihood of the data with the posterior integrated out. 
     708  virtual double logpred(const vec &dt) const {it_error("Not implemented"); return 0.0;} 
     709  //! Matrix version of logpred 
     710  vec logpred_m(const mat &dt) const {vec tmp(dt.cols()); for (int i = 0; i < dt.cols(); i++) {tmp(i) = logpred(dt.get_col(i));} return tmp;} 
     711 
     712  //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$ 
     713  virtual epdf* epredictor() const {it_error("Not implemented"); return NULL;}; 
     714  //!Constructs a conditional density 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) 
     715  virtual mpdf* predictor() const {it_error("Not implemented"); return NULL;}; 
     716  //!@} 
     717 
     718  //! \name Extension to conditional BM 
     719  //! This extension is useful e.g. in Marginalized Particle Filter (\ref bdm::MPF). 
     720  //! Alternatively, it can be used for automated connection to DS when the condition is observed 
     721  //!@{ 
     722 
     723  //! Name of extension variable 
     724  RV rvc; 
     725  //! access function 
     726  const RV& _rvc() const {return rvc;} 
     727 
     728  //! Substitute \c val for \c rvc. 
     729  virtual void condition(const vec &val) {it_error("Not implemented!");}; 
     730 
     731  //!@} 
     732 
     733 
     734  //! \name Access to attributes 
     735  //!@{ 
     736 
     737  const RV& _drv() const {return drv;} 
     738  void set_drv(const RV &rv) {drv = rv;} 
     739  void set_rv(const RV &rv) {const_cast<epdf&>(posterior()).set_rv(rv);} 
     740  double _ll() const {return ll;} 
     741  void set_evalll(bool evl0) {evalll = evl0;} 
     742  virtual const epdf& posterior() const = 0; 
     743  virtual const epdf* _e() const = 0; 
     744  //!@} 
     745 
     746  //! \name Logging of results 
     747  //!@{ 
     748 
     749  //! Set boolean options from a string recognized are: "logbounds,logll" 
     750  virtual void set_options(const string &opt) { 
     751    LFlags(0) = 1; 
     752    if (opt.find("logbounds") != string::npos) {LFlags(1) = 1; LFlags(2) = 1;} 
     753    if (opt.find("logll") != string::npos) {LFlags(3) = 1;} 
     754  } 
     755  //! IDs of storages in loggers 4:[1=mean,2=lb,3=ub,4=ll] 
     756  ivec LIDs; 
     757 
     758  //! Flags for logging - same size as LIDs, each entry correspond to the same in LIDs 
     759  ivec LFlags; 
     760  //! Add all logged variables to a logger 
     761  virtual void log_add(logger &L, const string &name = "") { 
     762    // internal 
     763    RV r; 
     764    if (posterior().isnamed()) {r = posterior()._rv();} 
     765    else {r = RV("est", posterior().dimension());}; 
     766 
     767    // Add mean value 
     768    if (LFlags(0)) LIDs(0) = L.add(r, name + "mean_"); 
     769    if (LFlags(1)) LIDs(1) = L.add(r, name + "lb_"); 
     770    if (LFlags(2)) LIDs(2) = L.add(r, name + "ub_"); 
     771    if (LFlags(3)) LIDs(3) = L.add(RV("ll", 1), name);    //TODO: "local" RV 
     772  } 
     773  virtual void logit(logger &L) { 
     774    L.logit(LIDs(0), posterior().mean()); 
     775    if (LFlags(1) || LFlags(2)) {  //if one of them is off, its LID==-1 and will not be stored 
     776      vec ub, lb; 
     777      posterior().qbounds(lb, ub); 
     778      L.logit(LIDs(1), lb); 
     779      L.logit(LIDs(2), ub); 
     780    } 
     781    if (LFlags(3)) L.logit(LIDs(3), ll); 
     782  } 
     783  //!@} 
    757784}; 
    758785