root/bdm/stat/libBM.h @ 357

Revision 357, 24.1 kB (checked in by mido, 15 years ago)

mnoho zmen:
1) presun FindXXX modulu do \system
2) zalozeni dokumentace \doc\local\library_structure.dox
3) presun obsahu \tests\UI primo do \tests
4) namisto \INSTALL zalozen \install.html, je to vhodnejsi pro uzivatele WINDOWS, a snad i obecne
5) snaha o predelani veskerych UI podle nove koncepce, soubory pmsm_ui.h, arx_ui.h, KF_ui.h, libDS_ui.h, libEF_ui.h a loggers_ui.h ponechavam
jen zdokumentacnich duvodu, nic by na nich jiz nemelo zaviset, a po zkontrolovani spravnosti provedenych uprav by mely byt smazany
6) predelani estimatoru tak, aby fungoval s novym UI konceptem
7) vytazeni tridy bdmroot do samostatneho souboru \bdm\bdmroot.h
8) pridana dokumentace pro zacleneni programu ASTYLE do Visual studia, ASTYLE pridan do instalacniho balicku pro Windows

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