root/bdm/stat/libBM.h @ 364

Revision 364, 24.1 kB (checked in by smidl, 15 years ago)

compile fixes

  • 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};
196UIREGISTER(RV);
197
198//! Concat two random variables
199RV concat ( const RV &rv1, const RV &rv2 );
200
201//!Default empty RV that can be used as default argument
202extern RV RV0;
203
204//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv
205
206class fnc :public bdmroot {
207protected:
208        //! Length of the output vector
209        int dimy;
210public:
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;}
223};
224
225class mpdf;
226
227//! Probability density function with numerical statistics, e.g. posterior density.
228
229class epdf : public bdmroot {
230protected:
231        //! dimension of the random variable
232        int dim;
233        //! Description of the random variable
234        RV rv;
235
236public:
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        //!@}
304
305};
306
307
308//! Conditional probability density, e.g. modeling some dependencies.
309//TODO Samplecond can be generalized
310
311class mpdf : public bdmroot {
312protected:
313        //!dimension of the condition
314        int dimc;
315        //! random variable in condition
316        RV rvc;
317        //! pointer to internal epdf
318        epdf* ep;
319public:
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        //!@}
372};
373
374/*! \brief DataLink is a connection between two data vectors Up and Down
375
376Up can be longer than Down. Down must be fully present in Up (TODO optional)
377See chart:
378\dot
379digraph datalink {
380        node [shape=record];
381        subgraph cluster0 {
382                label = "Up";
383        up [label="<1>|<2>|<3>|<4>|<5>"];
384                color = "white"
385}
386        subgraph cluster1{
387                label = "Down";
388                labelloc = b;
389        down [label="<1>|<2>|<3>"];
390                color = "white"
391}
392    up:1 -> down:1;
393    up:3 -> down:2;
394    up:5 -> down:3;
395}
396\enddot
397
398*/
399class datalink {
400protected:
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;
407public:
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        }
438};
439
440//! data link between
441class datalink_m2e: public datalink {
442protected:
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
450public:
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        }
471};
472//!DataLink is a connection between mpdf and its superordinate (Up)
473//! This class links
474class datalink_m2m: public datalink_m2e {
475protected:
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;
480public:
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
497
498};
499
500/*!
501@brief Class for storing results (and semi-results) of an experiment
502
503This 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.
504 */
505class logger : public bdmroot {
506protected:
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;
511public:
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() {};
542
543};
544
545/*! \brief Unconditional mpdf, allows using epdf in the role of mpdf.
546
547*/
548class mepdf : public mpdf {
549public:
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 ) {}
554};
555
556//!\brief Abstract composition of pdfs, will be used for specific classes
557//!this abstract class is common to epdf and mpdf
558class compositepdf {
559protected:
560        //!Number of mpdfs in the composite
561        int n;
562        //! Elements of composition
563        Array<mpdf*> mpdfs;
564public:
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 );
570};
571
572/*! \brief Abstract class for discrete-time sources of data.
573
574The 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.
575Moreover, for controlled systems, it is able to receive the desired control action and perform it in the next step. (Or as soon as possible).
576
577*/
578
579class DS : public bdmroot {
580protected:
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;
589public:
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;}
627};
628
629/*! \brief Bayesian Model of a system, i.e. all uncertainty is modeled by probabilities.
630
631This object represents exact or approximate evaluation of the Bayes rule:
632\f[
633f(\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})}
634\f]
635
636Access to the resulting posterior density is via function \c posterior().
637
638As a "side-effect" it also evaluates log-likelihood of the data, which can be accessed via function _ll().
639It can also evaluate predictors of future values of \f$y_t\f$, see functions epredictor() and predictor().
640
641Alternatively, it can evaluate posterior density conditioned by a known constant, \f$ c_t \f$:
642\f[
643f(\theta_t | c_t, d_1,\ldots,d_t) \propto  f(y_t,\theta_t|c_t,\cdot, d_1,\ldots,d_{t-1})
644\f]
645
646The value of \f$ c_t \f$ is set by function condition().
647
648*/
649
650class BM :public bdmroot {
651protected:
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;
658public:
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        //!@}
757};
758
759
760}; //namespace
761#endif // BM_H
Note: See TracBrowser for help on using the browser.