root/bdm/stat/libBM.h @ 283

Revision 283, 22.5 kB (checked in by smidl, 15 years ago)

get rid of BMcond + adaptation in doprava/

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