root/bdm/stat/libBM.h @ 286

Revision 286, 22.8 kB (checked in by smidl, 15 years ago)

make mpdm work again

  • 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        //! set connection using indeces
404        void set_connection ( int ds, int us, const ivec &upind ) {
405                downsize = ds;
406                upsize = us;
407                v2v_up= upind;
408
409                it_assert_debug ( v2v_up.length() ==downsize,"rv is not fully in rv_up" );
410        }
411        //! Get val for myself from val of "Up"
412        vec pushdown ( const vec &val_up ) {
413                it_assert_debug ( upsize==val_up.length(),"Wrong val_up" );
414                return get_vec ( val_up,v2v_up );
415        }
416        //! Fill val of "Up" by my pieces
417        void pushup ( vec &val_up, const vec &val ) {
418                it_assert_debug ( downsize==val.length(),"Wrong val" );
419                it_assert_debug ( upsize==val_up.length(),"Wrong val_up" );
420                set_subvector ( val_up, v2v_up, val );
421        }
422};
423
424//! data link between
425class datalink_m2e: public datalink {
426protected:
427        //! Remember how long cond should be
428        int condsize;
429        //!upper_val-to-local_cond link, indeces of the upper val
430        ivec v2c_up;
431        //!upper_val-to-local_cond link, ideces of the local cond
432        ivec v2c_lo;
433
434public:
435        datalink_m2e() {};
436        //! Constructor
437        void set_connection ( const RV &rv,  const RV &rvc, const RV &rv_up ) {
438                datalink::set_connection ( rv,rv_up );
439                condsize=  rvc._dsize();
440                //establish v2c connection
441                rvc.dataind ( rv_up, v2c_lo, v2c_up );
442        }
443        //!Construct condition
444        vec get_cond ( const vec &val_up ) {
445                vec tmp ( condsize );
446                set_subvector ( tmp,v2c_lo,val_up ( v2c_up ) );
447                return tmp;
448        }
449        void pushup_cond ( vec &val_up, const vec &val, const vec &cond ) {
450                it_assert_debug ( downsize==val.length(),"Wrong val" );
451                it_assert_debug ( upsize==val_up.length(),"Wrong val_up" );
452                set_subvector ( val_up, v2v_up, val );
453                set_subvector ( val_up, v2c_up, cond );
454        }
455};
456//!DataLink is a connection between mpdf and its superordinate (Up)
457//! This class links
458class datalink_m2m: public datalink_m2e {
459protected:
460        //!cond-to-cond link, indeces of the upper cond
461        ivec c2c_up;
462        //!cond-to-cond link, indeces of the local cond
463        ivec c2c_lo;
464public:
465        //! Constructor
466        datalink_m2m() {};
467        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) {
468                datalink_m2e::set_connection ( rv, rvc, rv_up );
469                //establish c2c connection
470                rvc.dataind ( rvc_up, c2c_lo, c2c_up );
471                it_assert_debug ( c2c_lo.length() +v2c_lo.length() ==condsize, "cond is not fully given" );
472        }
473        //! Get cond for myself from val and cond of "Up"
474        vec get_cond ( const vec &val_up, const vec &cond_up ) {
475                vec tmp ( condsize );
476                set_subvector ( tmp,v2c_lo,val_up ( v2c_up ) );
477                set_subvector ( tmp,c2c_lo,cond_up ( c2c_up ) );
478                return tmp;
479        }
480        //! Fill
481
482};
483
484/*!
485@brief Class for storing results (and semi-results) of an experiment
486
487This 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.
488 */
489class logger : public bdmroot {
490protected:
491        //! RVs of all logged variables.
492        Array<RV> entries;
493        //! Names of logged quantities, e.g. names of algorithm variants
494        Array<string> names;
495public:
496        //!Default constructor
497        logger ( ) : entries ( 0 ),names ( 0 ) {}
498
499        //! returns an identifier which will be later needed for calling the \c logit() function
500        //! For empty RV it returns -1, this entry will be ignored by \c logit().
501        virtual int add ( const RV &rv, string name="" ) {
502                int id;
503                if ( rv._dsize() >0 ) {
504                        id=entries.length();
505                        names=concat ( names, name ); // diff
506                        entries.set_length ( id+1,true );
507                        entries ( id ) = rv;
508                }
509                else { id =-1;}
510                return id; // identifier of the last entry
511        }
512
513        //! log this vector
514        virtual void logit ( int id, const vec &v ) =0;
515
516        //! Shifts storage position for another time step.
517        virtual void step() =0;
518
519        //! Finalize storing information
520        virtual void finalize() {};
521
522        //! Initialize the storage
523        virtual void init() {};
524
525};
526
527/*! \brief Unconditional mpdf, allows using epdf in the role of mpdf.
528
529*/
530class mepdf : public mpdf {
531public:
532        //!Default constructor
533        mepdf ( const epdf* em ) :mpdf ( ) {ep=const_cast<epdf*> ( em );};
534        void condition ( const vec &cond ) {}
535};
536
537//!\brief Abstract composition of pdfs, will be used for specific classes
538//!this abstract class is common to epdf and mpdf
539class compositepdf {
540protected:
541        //!Number of mpdfs in the composite
542        int n;
543        //! Elements of composition
544        Array<mpdf*> mpdfs;
545public:
546        compositepdf ( Array<mpdf*> A0 ) : n ( A0.length() ), mpdfs ( A0 ) {};
547        //! find common rv, flag \param checkoverlap modifies whether overlaps are acceptable
548        RV getrv ( bool checkoverlap=false );
549        //! common rvc of all mpdfs is written to rvc
550        void setrvc ( const RV &rv, RV &rvc );
551};
552
553/*! \brief Abstract class for discrete-time sources of data.
554
555The 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.
556Moreover, for controlled systems, it is able to receive the desired control action and perform it in the next step. (Or as soon as possible).
557
558*/
559
560class DS : public bdmroot {
561protected:
562        int dtsize;
563        int utsize;
564        //!Description of data returned by \c getdata().
565        RV Drv;
566        //!Description of data witten by by \c write().
567        RV Urv; //
568        //! Remember its own index in Logger L
569        int L_dt, L_ut;
570public:
571        //! default constructors
572        DS() :Drv ( ),Urv ( ) {};
573        //! Returns full vector of observed data=[output, input]
574        virtual void getdata ( vec &dt ) {it_error ( "abstract class" );};
575        //! Returns data records at indeces.
576        virtual void getdata ( vec &dt, const ivec &indeces ) {it_error ( "abstract class" );};
577        //! Accepts action variable and schedule it for application.
578        virtual void write ( vec &ut ) {it_error ( "abstract class" );};
579        //! Accepts action variables at specific indeces
580        virtual void write ( vec &ut, const ivec &indeces ) {it_error ( "abstract class" );};
581
582        //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system.
583        virtual void step() =0;
584
585        //! Register DS for logging into logger L
586        virtual void log_add ( logger &L ) {
587                it_assert_debug ( dtsize==Drv._dsize(),"" );
588                it_assert_debug ( utsize==Urv._dsize(),"" );
589
590                L_dt=L.add ( Drv,"" );
591                L_ut=L.add ( Urv,"" );
592        }
593        //! Register DS for logging into logger L
594        virtual void logit ( logger &L ) {
595                vec tmp ( Drv._dsize() +Urv._dsize() );
596                getdata ( tmp );
597                // d is first in getdata
598                L.logit ( L_dt,tmp.left ( Drv._dsize() ) );
599                // u follows after d in getdata
600                L.logit ( L_ut,tmp.mid ( Drv._dsize(), Urv._dsize() ) );
601        }
602        //!access function
603        virtual RV _drv() const {return concat ( Drv,Urv );}
604        //!access function
605        const RV& _urv() const {return Urv;}
606};
607
608/*! \brief Bayesian Model of a system, i.e. all uncertainty is modeled by probabilities.
609
610This object represents exact or approximate evaluation of the Bayes rule:
611\f[
612f(\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})}
613\f]
614
615Access to the resulting posterior density is via function \c posterior().
616
617As a "side-effect" it also evaluates log-likelihood of the data, which can be accessed via function _ll().
618It can also evaluate predictors of future values of \f$y_t\f$, see functions epredictor() and predictor().
619
620Alternatively, it can evaluate posterior density conditioned by a known constant, \f$ c_t \f$:
621\f[
622f(\theta_t | c_t, d_1,\ldots,d_t) \propto  f(y_t,\theta_t|c_t,\cdot, d_1,\ldots,d_{t-1})
623\f]
624
625The value of \f$ c_t \f$ is set by function condition().
626
627*/
628
629class BM :public bdmroot {
630protected:
631        //! Random variable of the data (optional)
632        RV drv;
633        //!Logarithm of marginalized data likelihood.
634        double ll;
635        //!  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.
636        bool evalll;
637public:
638        //! \name Constructors
639        //! @{
640
641        BM () :ll ( 0 ),evalll ( true ), LIDs ( 3 ), opt_L_bounds ( false ) {};
642        BM ( const BM &B ) :  drv ( B.drv ), ll ( B.ll ), evalll ( B.evalll ) {}
643        //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually!
644        //! Prototype: \code BM* _copy_() const {return new BM(*this);} \endcode
645        virtual BM* _copy_ () const {return NULL;};
646        //!@}
647
648        //! \name Mathematical operations
649        //!@{
650
651        /*! \brief Incremental Bayes rule
652        @param dt vector of input data
653        */
654        virtual void bayes ( const vec &dt ) = 0;
655        //! Batch Bayes rule (columns of Dt are observations)
656        virtual void bayesB ( const mat &Dt );
657        //! Evaluates predictive log-likelihood of the given data record
658        //! I.e. marginal likelihood of the data with the posterior integrated out.
659        virtual double logpred ( const vec &dt ) const{it_error ( "Not implemented" );return 0.0;}
660        //! Matrix version of logpred
661        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;}
662
663        //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$
664        virtual epdf* epredictor ( ) const {it_error ( "Not implemented" );return NULL;};
665        //!Constructs a conditional density 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t})
666        virtual mpdf* predictor ( ) const {it_error ( "Not implemented" );return NULL;};
667        //!@}
668
669        //! \name Extension to conditional BM
670        //! This extension is useful e.g. in Marginalized Particle Filter (\ref bdm::MPF).
671        //! Alternatively, it can be used for automated connection to DS when the condition is observed
672        //!@{
673
674        //! Name of extension variable
675        RV rvc;
676        //! access function
677        const RV& _rvc() const {return rvc;}
678
679        //! Substitute \c val for \c rvc.
680        virtual void condition ( const vec &val ) {it_error ( "Not implemented!" );};
681
682        //!@}
683
684
685        //! \name Access to attributes
686        //!@{
687
688        const RV& _drv() const {return drv;}
689        void set_drv ( const RV &rv ) {drv=rv;}
690        void set_rv ( const RV &rv ) {const_cast<epdf&> ( posterior() ).set_rv ( rv );}
691        double _ll() const {return ll;}
692        void set_evalll ( bool evl0 ) {evalll=evl0;}
693        virtual const epdf& posterior() const =0;
694        virtual const epdf* _e() const =0;
695        //!@}
696
697        //! \name Logging of results
698        //!@{
699
700        //! Set boolean options from a string
701        void set_options ( const string &opt ) {
702                opt_L_bounds= ( opt.find ( "logbounds" ) !=string::npos );
703        }
704        //! IDs of storages in loggers
705        ivec LIDs;
706
707        //! Option for logging bounds
708        bool opt_L_bounds;
709        //! Add all logged variables to a logger
710        void log_add ( logger *L, const string &name="" ) {
711                // internal
712                RV r;
713                if ( posterior().isnamed() ) {r=posterior()._rv();}
714                else{r=RV ( "est", posterior().dimension() );};
715
716                // Add mean value
717                LIDs ( 0 ) =L->add ( r,name );
718                if ( opt_L_bounds ) {
719                        LIDs ( 1 ) =L->add ( r,name+"_lb" );
720                        LIDs ( 2 ) =L->add ( r,name+"_ub" );
721                }
722        }
723        void logit ( logger *L ) {
724                L->logit ( LIDs ( 0 ), posterior().mean() );
725                if ( opt_L_bounds ) {
726                        vec ub,lb;
727                        posterior().qbounds ( lb,ub );
728                        L->logit ( LIDs ( 1 ), lb );
729                        L->logit ( LIDs ( 2 ), ub );
730                }
731        }
732        //!@}
733};
734
735}; //namespace
736#endif // BM_H
Note: See TracBrowser for help on using the browser.