root/bdm/stat/libBM.h @ 351

Revision 351, 23.9 kB (checked in by mido, 15 years ago)

par uprav v UI, nikoli finalni verze, presto je zahodno ji ulozit jako zalohu - uz behaji vsechny podstatne funkce vcetne nacitani Array<T>

  • Property svn:eol-style set to native
Line 
1/*!
2  \file
3  \brief Bayesian Models (bm) that use Bayes rule to learn from observations
4  \author Vaclav Smidl.
5
6  -----------------------------------
7  BDM++ - C++ library for Bayesian Decision Making under Uncertainty
8
9  Using IT++ for numerical operations
10  -----------------------------------
11*/
12
13#ifndef BM_H
14#define BM_H
15
16#include <map>
17
18#include "../itpp_ext.h"
19#include "../libconfig/libconfig.h++"
20
21
22using namespace libconfig;
23
24using namespace itpp;
25using namespace std;
26
27namespace bdm {
28
29//! Root class of BDM objects
30
31class bdmroot {
32public:
33        //! make sure this is a virtual object
34        virtual ~bdmroot() 
35        {
36        }
37
38        //! This method returns a basic info about the current instance
39        virtual string ToString()
40        {
41                return "";
42        }
43
44        //! This method arrange instance properties according the data stored in the Setting structure
45        virtual void from_setting( const Setting &root )
46        {
47        }
48
49        //! This method save all the instance properties into the Setting structure
50        virtual void to_setting( Setting &root ) const
51        {       
52        }
53};
54
55typedef std::map<string, int> RVmap;
56extern ivec RV_SIZES;
57extern Array<string> RV_NAMES;
58
59//! Structure of RV (used internally), i.e. expanded RVs
60class str {
61public:
62        //! vector id ids (non-unique!)
63        ivec ids;
64        //! vector of times
65        ivec times;
66        //!Default constructor
67        str ( ivec ids0, ivec times0 ) :ids ( ids0 ),times ( times0 ) {
68                it_assert_debug ( times0.length() ==ids0.length(),"Incompatible input" );
69        };
70};
71
72/*!
73* \brief Class representing variables, most often random variables
74
75The purpose of this class is to decribe a vector of data. Such description is used for connecting various vectors between each other, see class datalink.
76
77The class is implemented using global variables to assure uniqueness of description:
78
79 In is a vector
80\dot
81digraph datalink {
82rankdir=LR;
83subgraph cluster0 {
84node [shape=record];
85label = "RV_MAP \n std::map<string,int>";
86map [label="{{\"a\"| \"b\" | \"c\"} | {<3> 3 |<1> 1|<2> 2}}"];
87color = "white"
88}
89subgraph cluster1{
90node [shape=record];
91label = "RV_NAMES";
92names [label="{<1> \"b\" | <2> \"c\" | <3>\"a\" }"];
93color = "white"
94}
95subgraph cluster2{
96node [shape=record];
97label = "RV_SIZES";
98labelloc = b;
99sizes [label="{<1>1 |<2> 4 |<3> 1}"];
100color = "white"
101}
102map:1 -> names:1;
103map:1 -> sizes:1;
104map:3 -> names:3;
105map:3 -> sizes:3;
106}
107\enddot
108*/
109
110class RV :public bdmroot {
111protected:
112        //! size of the data vector
113        int dsize;
114        //! number of individual rvs
115        int len;
116        //! Vector of unique IDs
117        ivec ids;
118        //! Vector of shifts from current time
119        ivec times;
120
121private:
122        //! auxiliary function used in constructor
123        void init ( Array<std::string> in_names, ivec in_sizes, ivec in_times );
124        int init ( const  string &name, int size );
125public:
126        //! \name Constructors
127        //!@{
128
129        //! Full constructor
130        RV ( Array<std::string> in_names, ivec in_sizes, ivec in_times ) {init ( in_names,in_sizes,in_times );};
131        //! Constructor with times=0
132        RV ( Array<std::string> in_names, ivec in_sizes ) {init ( in_names,in_sizes,zeros_i ( in_names.length() ) );};
133        //! Constructor with sizes=1, times=0
134        RV ( Array<std::string> in_names ) {init ( in_names,ones_i ( in_names.length() ),zeros_i ( in_names.length() ) );}
135        //! Constructor of empty RV
136        RV () :dsize ( 0 ),len ( 0 ),ids ( 0 ),times ( 0 ) {};
137        //! Constructor of a single RV with given id
138        RV ( string name, int sz, int tm=0 );
139        //!@}
140
141        //! \name Access functions
142        //!@{
143
144        //! Printing output e.g. for debugging.
145        friend std::ostream &operator<< ( std::ostream &os, const RV &rv );
146        int _dsize() const {return dsize;} ;
147        //! Recount size of the corresponding data vector
148        int countsize() const;
149        ivec cumsizes() const;
150        int length() const {return len;} ;
151        int id ( int at ) const{return ids ( at );};
152        int size ( int at ) const {return RV_SIZES ( ids ( at ) );};
153        int time ( int at ) const{return times ( at );};
154        std::string name ( int at ) const {return RV_NAMES ( ids ( at ) );};
155        void set_time ( int at, int time0 ) {times ( at ) =time0;};
156        //!@}
157
158        //TODO why not inline and later??
159
160        //! \name Algebra on Random Variables
161        //!@{
162
163        //! Find indices of self in another rv, \return ivec of the same size as self.
164        ivec findself ( const RV &rv2 ) const;
165        //! Compare if \c rv2 is identical to this \c RV
166        bool equal ( const RV &rv2 ) const;
167        //! Add (concat) another variable to the current one, \return true if all rv2 were added, false if rv2 is in conflict
168        bool add ( const RV &rv2 );
169        //! Subtract  another variable from the current one
170        RV subt ( const RV &rv2 ) const;
171        //! Select only variables at indeces ind
172        RV subselect ( const ivec &ind ) const;
173        //! Select only variables at indeces ind
174        RV operator() ( const ivec &ind ) const {return subselect ( ind );};
175        //! Select from data vector starting at di1 to di2
176        RV operator() ( int di1, int di2 ) const {
177                ivec sz=cumsizes();
178                int i1=0;
179                while ( sz ( i1 ) <di1 ) i1++;
180                int i2=i1;
181                while ( sz ( i2 ) <di2 ) i2++;
182                return subselect ( linspace ( i1,i2 ) );
183        };
184        //! Shift \c time shifted by delta.
185        void t ( int delta );
186        //!@}
187
188        //!\name Relation to vectors
189        //!@{
190
191        //! generate \c str from rv, by expanding sizes
192        str tostr() const;
193        //! when this rv is a part of bigger rv, this function returns indeces of self in the data vector of the bigger crv.
194        //! Then, data can be copied via: data_of_this = cdata(ind);
195        ivec dataind ( const RV &crv ) const;
196        //! generate mutual indeces when copying data betwenn self and crv.
197        //! Data are copied via: data_of_this(selfi) = data_of_rv2(rv2i)
198        void dataind ( const RV &rv2, ivec &selfi, ivec &rv2i ) const;
199        //! Minimum time-offset
200        int mint () const {return min ( times );};
201        //!@}
202
203};
204
205
206//! Concat two random variables
207RV concat ( const RV &rv1, const RV &rv2 );
208
209//!Default empty RV that can be used as default argument
210extern RV RV0;
211
212//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv
213
214class fnc :public bdmroot {
215protected:
216        //! Length of the output vector
217        int dimy;
218public:
219        //!default constructor
220        fnc ( ) {};
221        //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond
222        virtual vec eval ( const vec &cond ) {
223                return vec ( 0 );
224        };
225
226        //! function substitutes given value into an appropriate position
227        virtual void condition ( const vec &val ) {};
228
229        //! access function
230        int dimension() const{return dimy;}
231};
232
233class mpdf;
234
235//! Probability density function with numerical statistics, e.g. posterior density.
236
237class epdf :public bdmroot {
238protected:
239        //! dimension of the random variable
240        int dim;
241        //! Description of the random variable
242        RV rv;
243
244public:
245        /*! \name Constructors
246         Construction of each epdf should support two types of constructors:
247        \li empty constructor,
248        \li copy constructor,
249
250        The following constructors should be supported for convenience:
251        \li constructor followed by calling \c set_parameters()
252        \li constructor accepting random variables calling \c set_rv()
253
254         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.
255        @{*/
256        epdf() :dim ( 0 ),rv ( ) {};
257        epdf ( const epdf &e ) :dim ( e.dim ),rv ( e.rv ) {};
258        epdf ( const RV &rv0 ) {set_rv ( rv0 );};
259        void set_parameters ( int dim0 ) {dim=dim0;}
260        //!@}
261
262        //! \name Matematical Operations
263        //!@{
264
265        //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$
266        virtual vec sample () const {it_error ( "not implemneted" );return vec ( 0 );};
267        //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$  from density \f$ f_x(rv)\f$
268        virtual mat sample_m ( int N ) const;
269        //! Compute log-probability of argument \c val
270        virtual double evallog ( const vec &val ) const {it_error ( "not implemneted" );return 0.0;};
271        //! Compute log-probability of multiple values argument \c val
272        virtual vec evallog_m ( const mat &Val ) const {
273                vec x ( Val.cols() );
274                for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evallog ( Val.get_col ( i ) ) ;}
275                return x;
276        }
277        //! Return conditional density on the given RV, the remaining rvs will be in conditioning
278        virtual mpdf* condition ( const RV &rv ) const  {it_warning ( "Not implemented" ); return NULL;}
279        //! Return marginal density on the given RV, the remainig rvs are intergrated out
280        virtual epdf* marginal ( const RV &rv ) const {it_warning ( "Not implemented" ); return NULL;}
281        //! return expected value
282        virtual vec mean() const {it_error ( "not implemneted" );return vec ( 0 );};
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(); vec std=sqrt ( variance() );
288                lb = mea-2*std; ub=mea+2*std;
289        };
290        //!@}
291
292        //! \name Connection to other classes
293        //! Description of the random quantity via attribute \c rv is optional.
294        //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization
295        //! and \c conditioning \c rv has to be set. NB:
296        //! @{
297
298        //!Name its rv
299        void set_rv ( const RV &rv0 ) {rv = rv0; }//it_assert_debug(isnamed(),""); };
300        //! True if rv is assigned
301        bool isnamed() const {bool b= ( dim==rv._dsize() );return b;}
302        //! Return name (fails when isnamed is false)
303        const RV& _rv() const {it_assert_debug ( isnamed(),"" ); return rv;}
304        //!@}
305
306        //! \name Access to attributes
307        //! @{
308
309        //! Size of the random variable
310        int dimension() const {return dim;}
311        //!@}
312
313};
314
315
316//! Conditional probability density, e.g. modeling some dependencies.
317//TODO Samplecond can be generalized
318
319class mpdf : public bdmroot {
320protected:
321        //!dimension of the condition
322        int dimc;
323        //! random variable in condition
324        RV rvc;
325        //! pointer to internal epdf
326        epdf* ep;
327public:
328        //! \name Constructors
329        //! @{
330
331        mpdf ( ) :dimc ( 0 ),rvc ( ) {};
332        //! copy constructor does not set pointer \c ep - has to be done in offsprings!
333        mpdf ( const mpdf &m ) :dimc ( m.dimc ),rvc ( m.rvc ) {};
334        //!@}
335
336        //! \name Matematical operations
337        //!@{
338
339        //! 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
340        virtual vec samplecond ( const vec &cond ) {
341                this->condition ( cond );
342                vec temp= ep->sample();
343                return temp;
344        };
345        //! 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
346        virtual mat samplecond_m ( const vec &cond, int N ) {
347                this->condition ( cond );
348                mat temp ( ep->dimension(),N ); vec smp ( ep->dimension() );
349                for ( int i=0;i<N;i++ ) {smp=ep->sample() ;temp.set_col ( i, smp );}
350                return temp;
351        };
352        //! Update \c ep so that it represents this mpdf conditioned on \c rvc = cond
353        virtual void condition ( const vec &cond ) {it_error ( "Not implemented" );};
354
355        //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently.
356        virtual double evallogcond ( const vec &dt, const vec &cond ) {
357                double tmp; this->condition ( cond );tmp = ep->evallog ( dt );          it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); return tmp;
358        };
359
360        //! Matrix version of evallogcond
361        virtual vec evallogcond_m ( const mat &Dt, const vec &cond ) {this->condition ( cond );return ep->evallog_m ( Dt );};
362
363        //! \name Access to attributes
364        //! @{
365
366        RV _rv() {return ep->_rv();}
367        RV _rvc() {it_assert_debug ( isnamed(),"" ); return rvc;}
368        int dimension() {return ep->dimension();}
369        int dimensionc() {return dimc;}
370        epdf& _epdf() {return *ep;}
371        epdf* _e() {return ep;}
372        //!@}
373
374        //! \name Connection to other objects
375        //!@{
376        void set_rvc ( const RV &rvc0 ) {rvc=rvc0;}
377        void set_rv ( const RV &rv0 ) {ep->set_rv ( rv0 );}
378        bool isnamed() {return ( ep->isnamed() ) && ( dimc==rvc._dsize() );}
379        //!@}
380};
381
382/*! \brief DataLink is a connection between two data vectors Up and Down
383
384Up can be longer than Down. Down must be fully present in Up (TODO optional)
385See chart:
386\dot
387digraph datalink {
388        node [shape=record];
389        subgraph cluster0 {
390                label = "Up";
391        up [label="<1>|<2>|<3>|<4>|<5>"];
392                color = "white"
393}
394        subgraph cluster1{
395                label = "Down";
396                labelloc = b;
397        down [label="<1>|<2>|<3>"];
398                color = "white"
399}
400    up:1 -> down:1;
401    up:3 -> down:2;
402    up:5 -> down:3;
403}
404\enddot
405
406*/
407class datalink {
408protected:
409        //! Remember how long val should be
410        int downsize;
411        //! Remember how long val of "Up" should be
412        int upsize;
413        //! val-to-val link, indeces of the upper val
414        ivec v2v_up;
415public:
416        //! Constructor
417        datalink () {};
418        datalink ( const RV &rv, const RV &rv_up ) {set_connection ( rv,rv_up );};
419        //! set connection, rv must be fully present in rv_up
420        void set_connection ( const RV &rv, const RV &rv_up ) {
421                downsize = rv._dsize();
422                upsize = rv_up._dsize();
423                v2v_up= ( rv.dataind ( rv_up ) );
424
425                it_assert_debug ( v2v_up.length() ==downsize,"rv is not fully in rv_up" );
426        }
427        //! set connection using indeces
428        void set_connection ( int ds, int us, const ivec &upind ) {
429                downsize = ds;
430                upsize = us;
431                v2v_up= upind;
432
433                it_assert_debug ( v2v_up.length() ==downsize,"rv is not fully in rv_up" );
434        }
435        //! Get val for myself from val of "Up"
436        vec pushdown ( const vec &val_up ) {
437                it_assert_debug ( upsize==val_up.length(),"Wrong val_up" );
438                return get_vec ( val_up,v2v_up );
439        }
440        //! Fill val of "Up" by my pieces
441        void pushup ( vec &val_up, const vec &val ) {
442                it_assert_debug ( downsize==val.length(),"Wrong val" );
443                it_assert_debug ( upsize==val_up.length(),"Wrong val_up" );
444                set_subvector ( val_up, v2v_up, val );
445        }
446};
447
448//! data link between
449class datalink_m2e: public datalink {
450protected:
451        //! Remember how long cond should be
452        int condsize;
453        //!upper_val-to-local_cond link, indeces of the upper val
454        ivec v2c_up;
455        //!upper_val-to-local_cond link, ideces of the local cond
456        ivec v2c_lo;
457
458public:
459        datalink_m2e() {};
460        //! Constructor
461        void set_connection ( const RV &rv,  const RV &rvc, const RV &rv_up ) {
462                datalink::set_connection ( rv,rv_up );
463                condsize=  rvc._dsize();
464                //establish v2c connection
465                rvc.dataind ( rv_up, v2c_lo, v2c_up );
466        }
467        //!Construct condition
468        vec get_cond ( const vec &val_up ) {
469                vec tmp ( condsize );
470                set_subvector ( tmp,v2c_lo,val_up ( v2c_up ) );
471                return tmp;
472        }
473        void pushup_cond ( vec &val_up, const vec &val, const vec &cond ) {
474                it_assert_debug ( downsize==val.length(),"Wrong val" );
475                it_assert_debug ( upsize==val_up.length(),"Wrong val_up" );
476                set_subvector ( val_up, v2v_up, val );
477                set_subvector ( val_up, v2c_up, cond );
478        }
479};
480//!DataLink is a connection between mpdf and its superordinate (Up)
481//! This class links
482class datalink_m2m: public datalink_m2e {
483protected:
484        //!cond-to-cond link, indeces of the upper cond
485        ivec c2c_up;
486        //!cond-to-cond link, indeces of the local cond
487        ivec c2c_lo;
488public:
489        //! Constructor
490        datalink_m2m() {};
491        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) {
492                datalink_m2e::set_connection ( rv, rvc, rv_up );
493                //establish c2c connection
494                rvc.dataind ( rvc_up, c2c_lo, c2c_up );
495                it_assert_debug ( c2c_lo.length() +v2c_lo.length() ==condsize, "cond is not fully given" );
496        }
497        //! Get cond for myself from val and cond of "Up"
498        vec get_cond ( const vec &val_up, const vec &cond_up ) {
499                vec tmp ( condsize );
500                set_subvector ( tmp,v2c_lo,val_up ( v2c_up ) );
501                set_subvector ( tmp,c2c_lo,cond_up ( c2c_up ) );
502                return tmp;
503        }
504        //! Fill
505
506};
507
508/*!
509@brief Class for storing results (and semi-results) of an experiment
510
511This 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.
512 */
513class logger : public bdmroot {
514protected:
515        //! RVs of all logged variables.
516        Array<RV> entries;
517        //! Names of logged quantities, e.g. names of algorithm variants
518        Array<string> names;
519public:
520        //!Default constructor
521        logger ( ) : entries ( 0 ),names ( 0 ) {}
522
523        //! returns an identifier which will be later needed for calling the \c logit() function
524        //! For empty RV it returns -1, this entry will be ignored by \c logit().
525        virtual int add ( const RV &rv, string prefix="" ) {
526                int id;
527                if ( rv._dsize() >0 ) {
528                        id=entries.length();
529                        names=concat ( names, prefix); // diff
530                        entries.set_length ( id+1,true );
531                        entries ( id ) = rv;
532                }
533                else { id =-1;}
534                return id; // identifier of the last entry
535        }
536
537        //! log this vector
538        virtual void logit ( int id, const vec &v ) =0;
539        //! log this double
540        virtual void logit ( int id, const double &d ) =0;
541
542        //! Shifts storage position for another time step.
543        virtual void step() =0;
544
545        //! Finalize storing information
546        virtual void finalize() {};
547
548        //! Initialize the storage
549        virtual void init() {};
550
551};
552
553/*! \brief Unconditional mpdf, allows using epdf in the role of mpdf.
554
555*/
556class mepdf : public mpdf {
557public:
558        //!Default constructor
559        mepdf ( epdf* em ) :mpdf ( ) {ep= em ;};
560        mepdf (const epdf* em ) :mpdf ( ) {ep=const_cast<epdf*>( em );};
561        void condition ( const vec &cond ) {}
562};
563
564//!\brief Abstract composition of pdfs, will be used for specific classes
565//!this abstract class is common to epdf and mpdf
566class compositepdf {
567protected:
568        //!Number of mpdfs in the composite
569        int n;
570        //! Elements of composition
571        Array<mpdf*> mpdfs;
572public:
573        compositepdf ( Array<mpdf*> A0 ) : n ( A0.length() ), mpdfs ( A0 ) {};
574        //! find common rv, flag \param checkoverlap modifies whether overlaps are acceptable
575        RV getrv ( bool checkoverlap=false );
576        //! common rvc of all mpdfs is written to rvc
577        void setrvc ( const RV &rv, RV &rvc );
578};
579
580/*! \brief Abstract class for discrete-time sources of data.
581
582The class abstracts operations of: (i) data aquisition, (ii) data-preprocessing, (iii) scaling of data, and (iv) data resampling from the task of estimation and control.
583Moreover, for controlled systems, it is able to receive the desired control action and perform it in the next step. (Or as soon as possible).
584
585*/
586
587class DS : public bdmroot {
588protected:
589        int dtsize;
590        int utsize;
591        //!Description of data returned by \c getdata().
592        RV Drv;
593        //!Description of data witten by by \c write().
594        RV Urv; //
595        //! Remember its own index in Logger L
596        int L_dt, L_ut;
597public:
598        //! default constructors
599        DS() :Drv ( ),Urv ( ) {};
600        //! Returns full vector of observed data=[output, input]
601        virtual void getdata ( vec &dt ) {it_error ( "abstract class" );};
602        //! Returns data records at indeces.
603        virtual void getdata ( vec &dt, const ivec &indeces ) {it_error ( "abstract class" );};
604        //! Accepts action variable and schedule it for application.
605        virtual void write ( vec &ut ) {it_error ( "abstract class" );};
606        //! Accepts action variables at specific indeces
607        virtual void write ( vec &ut, const ivec &indeces ) {it_error ( "abstract class" );};
608
609        //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system.
610        virtual void step() =0;
611
612        //! Register DS for logging into logger L
613        virtual void log_add ( logger &L ) {
614                it_assert_debug ( dtsize==Drv._dsize(),"" );
615                it_assert_debug ( utsize==Urv._dsize(),"" );
616
617                L_dt=L.add ( Drv,"" );
618                L_ut=L.add ( Urv,"" );
619        }
620        //! Register DS for logging into logger L
621        virtual void logit ( logger &L ) {
622                vec tmp ( Drv._dsize() +Urv._dsize() );
623                getdata ( tmp );
624                // d is first in getdata
625                L.logit ( L_dt,tmp.left ( Drv._dsize() ) );
626                // u follows after d in getdata
627                L.logit ( L_ut,tmp.mid ( Drv._dsize(), Urv._dsize() ) );
628        }
629        //!access function
630        virtual RV _drv() const {return concat ( Drv,Urv );}
631        //!access function
632        const RV& _urv() const {return Urv;}
633        //! set random rvariables
634        virtual void set_drv (const  RV &drv, const RV &urv) { Drv=drv;Urv=urv;}
635};
636
637/*! \brief Bayesian Model of a system, i.e. all uncertainty is modeled by probabilities.
638
639This object represents exact or approximate evaluation of the Bayes rule:
640\f[
641f(\theta_t | d_1,\ldots,d_t) = \frac{f(y_t|\theta_t,\cdot) f(\theta_t|d_1,\ldots,d_{t-1})}{f(y_t|d_1,\ldots,d_{t-1})}
642\f]
643
644Access to the resulting posterior density is via function \c posterior().
645
646As a "side-effect" it also evaluates log-likelihood of the data, which can be accessed via function _ll().
647It can also evaluate predictors of future values of \f$y_t\f$, see functions epredictor() and predictor().
648
649Alternatively, it can evaluate posterior density conditioned by a known constant, \f$ c_t \f$:
650\f[
651f(\theta_t | c_t, d_1,\ldots,d_t) \propto  f(y_t,\theta_t|c_t,\cdot, d_1,\ldots,d_{t-1})
652\f]
653
654The value of \f$ c_t \f$ is set by function condition().
655
656*/
657
658class BM :public bdmroot {
659protected:
660        //! Random variable of the data (optional)
661        RV drv;
662        //!Logarithm of marginalized data likelihood.
663        double ll;
664        //!  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.
665        bool evalll;
666public:
667        //! \name Constructors
668        //! @{
669
670        BM () :ll ( 0 ),evalll ( true ), LIDs ( 4 ), LFlags(4) {
671                LIDs=-1;/*empty IDs*/ LFlags=0; LFlags(0)=1;/*log only mean*/};
672        BM ( const BM &B ) :  drv ( B.drv ), ll ( B.ll ), evalll ( B.evalll ) {}
673        //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually!
674        //! Prototype: \code BM* _copy_() const {return new BM(*this);} \endcode
675        virtual BM* _copy_ () const {return NULL;};
676        //!@}
677
678        //! \name Mathematical operations
679        //!@{
680
681        /*! \brief Incremental Bayes rule
682        @param dt vector of input data
683        */
684        virtual void bayes ( const vec &dt ) = 0;
685        //! Batch Bayes rule (columns of Dt are observations)
686        virtual void bayesB ( const mat &Dt );
687        //! Evaluates predictive log-likelihood of the given data record
688        //! I.e. marginal likelihood of the data with the posterior integrated out.
689        virtual double logpred ( const vec &dt ) const{it_error ( "Not implemented" );return 0.0;}
690        //! Matrix version of logpred
691        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;}
692
693        //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$
694        virtual epdf* epredictor ( ) const {it_error ( "Not implemented" );return NULL;};
695        //!Constructs a conditional density 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t})
696        virtual mpdf* predictor ( ) const {it_error ( "Not implemented" );return NULL;};
697        //!@}
698
699        //! \name Extension to conditional BM
700        //! This extension is useful e.g. in Marginalized Particle Filter (\ref bdm::MPF).
701        //! Alternatively, it can be used for automated connection to DS when the condition is observed
702        //!@{
703
704        //! Name of extension variable
705        RV rvc;
706        //! access function
707        const RV& _rvc() const {return rvc;}
708
709        //! Substitute \c val for \c rvc.
710        virtual void condition ( const vec &val ) {it_error ( "Not implemented!" );};
711
712        //!@}
713
714
715        //! \name Access to attributes
716        //!@{
717
718        const RV& _drv() const {return drv;}
719        void set_drv ( const RV &rv ) {drv=rv;}
720        void set_rv ( const RV &rv ) {const_cast<epdf&> ( posterior() ).set_rv ( rv );}
721        double _ll() const {return ll;}
722        void set_evalll ( bool evl0 ) {evalll=evl0;}
723        virtual const epdf& posterior() const =0;
724        virtual const epdf* _e() const =0;
725        //!@}
726
727        //! \name Logging of results
728        //!@{
729
730        //! Set boolean options from a string recognized are: "logbounds,logll"
731        virtual void set_options ( const string &opt ) {
732                LFlags(0)=1;
733                if ( opt.find ( "logbounds" ) !=string::npos ) {LFlags(1)=1; LFlags(2)=1;}
734                if ( opt.find ( "logll" ) !=string::npos ) {LFlags(3)=1;}
735        }
736        //! IDs of storages in loggers 4:[1=mean,2=lb,3=ub,4=ll]
737        ivec LIDs;
738
739        //! Flags for logging - same size as LIDs, each entry correspond to the same in LIDs
740        ivec LFlags;
741        //! Add all logged variables to a logger
742        virtual void log_add ( logger &L, const string &name="" ) {
743                // internal
744                RV r;
745                if ( posterior().isnamed() ) {r=posterior()._rv();}
746                else{r=RV ( "est", posterior().dimension() );};
747
748                // Add mean value
749                if (LFlags(0)) LIDs ( 0 ) =L.add ( r,name+"mean_" );
750                if (LFlags(1)) LIDs ( 1 ) =L.add ( r,name+"lb_" );
751                if (LFlags(2)) LIDs ( 2 ) =L.add ( r,name+"ub_" );
752                if (LFlags(3)) LIDs ( 3 ) =L.add ( RV("ll",1),name ); //TODO: "local" RV
753        }
754        virtual void logit ( logger &L ) {
755                L.logit ( LIDs ( 0 ), posterior().mean() );
756                if ( LFlags(1) || LFlags(2)) { //if one of them is off, its LID==-1 and will not be stored
757                        vec ub,lb;
758                        posterior().qbounds ( lb,ub );
759                        L.logit ( LIDs ( 1 ), lb ); 
760                        L.logit ( LIDs ( 2 ), ub );
761                }
762                if (LFlags(3)) L.logit ( LIDs ( 3 ), ll );
763        }
764        //!@}
765};
766
767
768}; //namespace
769#endif // BM_H
Note: See TracBrowser for help on using the browser.