root/bdm/stat/libBM.h @ 340

Revision 340, 23.7 kB (checked in by mido, 15 years ago)

drobny patch libBM.h

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