root/bdm/stat/libBM.h @ 338

Revision 338, 23.4 kB (checked in by smidl, 15 years ago)

Multiple Models + changes in loggers

  • 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
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        //! log this double
516        virtual void logit ( int id, const double &d ) =0;
517
518        //! Shifts storage position for another time step.
519        virtual void step() =0;
520
521        //! Finalize storing information
522        virtual void finalize() {};
523
524        //! Initialize the storage
525        virtual void init() {};
526
527};
528
529/*! \brief Unconditional mpdf, allows using epdf in the role of mpdf.
530
531*/
532class mepdf : public mpdf {
533public:
534        //!Default constructor
535        mepdf ( epdf* em ) :mpdf ( ) {ep= em ;};
536        mepdf (const epdf* em ) :mpdf ( ) {ep=const_cast<epdf*>( em );};
537        void condition ( const vec &cond ) {}
538};
539
540//!\brief Abstract composition of pdfs, will be used for specific classes
541//!this abstract class is common to epdf and mpdf
542class compositepdf {
543protected:
544        //!Number of mpdfs in the composite
545        int n;
546        //! Elements of composition
547        Array<mpdf*> mpdfs;
548public:
549        compositepdf ( Array<mpdf*> A0 ) : n ( A0.length() ), mpdfs ( A0 ) {};
550        //! find common rv, flag \param checkoverlap modifies whether overlaps are acceptable
551        RV getrv ( bool checkoverlap=false );
552        //! common rvc of all mpdfs is written to rvc
553        void setrvc ( const RV &rv, RV &rvc );
554};
555
556/*! \brief Abstract class for discrete-time sources of data.
557
558The 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.
559Moreover, for controlled systems, it is able to receive the desired control action and perform it in the next step. (Or as soon as possible).
560
561*/
562
563class DS : public bdmroot {
564protected:
565        int dtsize;
566        int utsize;
567        //!Description of data returned by \c getdata().
568        RV Drv;
569        //!Description of data witten by by \c write().
570        RV Urv; //
571        //! Remember its own index in Logger L
572        int L_dt, L_ut;
573public:
574        //! default constructors
575        DS() :Drv ( ),Urv ( ) {};
576        //! Returns full vector of observed data=[output, input]
577        virtual void getdata ( vec &dt ) {it_error ( "abstract class" );};
578        //! Returns data records at indeces.
579        virtual void getdata ( vec &dt, const ivec &indeces ) {it_error ( "abstract class" );};
580        //! Accepts action variable and schedule it for application.
581        virtual void write ( vec &ut ) {it_error ( "abstract class" );};
582        //! Accepts action variables at specific indeces
583        virtual void write ( vec &ut, const ivec &indeces ) {it_error ( "abstract class" );};
584
585        //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system.
586        virtual void step() =0;
587
588        //! Register DS for logging into logger L
589        virtual void log_add ( logger &L ) {
590                it_assert_debug ( dtsize==Drv._dsize(),"" );
591                it_assert_debug ( utsize==Urv._dsize(),"" );
592
593                L_dt=L.add ( Drv,"" );
594                L_ut=L.add ( Urv,"" );
595        }
596        //! Register DS for logging into logger L
597        virtual void logit ( logger &L ) {
598                vec tmp ( Drv._dsize() +Urv._dsize() );
599                getdata ( tmp );
600                // d is first in getdata
601                L.logit ( L_dt,tmp.left ( Drv._dsize() ) );
602                // u follows after d in getdata
603                L.logit ( L_ut,tmp.mid ( Drv._dsize(), Urv._dsize() ) );
604        }
605        //!access function
606        virtual RV _drv() const {return concat ( Drv,Urv );}
607        //!access function
608        const RV& _urv() const {return Urv;}
609};
610
611/*! \brief Bayesian Model of a system, i.e. all uncertainty is modeled by probabilities.
612
613This object represents exact or approximate evaluation of the Bayes rule:
614\f[
615f(\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})}
616\f]
617
618Access to the resulting posterior density is via function \c posterior().
619
620As a "side-effect" it also evaluates log-likelihood of the data, which can be accessed via function _ll().
621It can also evaluate predictors of future values of \f$y_t\f$, see functions epredictor() and predictor().
622
623Alternatively, it can evaluate posterior density conditioned by a known constant, \f$ c_t \f$:
624\f[
625f(\theta_t | c_t, d_1,\ldots,d_t) \propto  f(y_t,\theta_t|c_t,\cdot, d_1,\ldots,d_{t-1})
626\f]
627
628The value of \f$ c_t \f$ is set by function condition().
629
630*/
631
632class BM :public bdmroot {
633protected:
634        //! Random variable of the data (optional)
635        RV drv;
636        //!Logarithm of marginalized data likelihood.
637        double ll;
638        //!  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.
639        bool evalll;
640public:
641        //! \name Constructors
642        //! @{
643
644        BM () :ll ( 0 ),evalll ( true ), LIDs ( 4 ), LFlags(4) {
645                LIDs=-1;/*empty IDs*/ LFlags=0; LFlags(0)=1;/*log only mean*/};
646        BM ( const BM &B ) :  drv ( B.drv ), ll ( B.ll ), evalll ( B.evalll ) {}
647        //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually!
648        //! Prototype: \code BM* _copy_() const {return new BM(*this);} \endcode
649        virtual BM* _copy_ () const {return NULL;};
650        //!@}
651
652        //! \name Mathematical operations
653        //!@{
654
655        /*! \brief Incremental Bayes rule
656        @param dt vector of input data
657        */
658        virtual void bayes ( const vec &dt ) = 0;
659        //! Batch Bayes rule (columns of Dt are observations)
660        virtual void bayesB ( const mat &Dt );
661        //! Evaluates predictive log-likelihood of the given data record
662        //! I.e. marginal likelihood of the data with the posterior integrated out.
663        virtual double logpred ( const vec &dt ) const{it_error ( "Not implemented" );return 0.0;}
664        //! Matrix version of logpred
665        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;}
666
667        //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$
668        virtual epdf* epredictor ( ) const {it_error ( "Not implemented" );return NULL;};
669        //!Constructs a conditional density 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t})
670        virtual mpdf* predictor ( ) const {it_error ( "Not implemented" );return NULL;};
671        //!@}
672
673        //! \name Extension to conditional BM
674        //! This extension is useful e.g. in Marginalized Particle Filter (\ref bdm::MPF).
675        //! Alternatively, it can be used for automated connection to DS when the condition is observed
676        //!@{
677
678        //! Name of extension variable
679        RV rvc;
680        //! access function
681        const RV& _rvc() const {return rvc;}
682
683        //! Substitute \c val for \c rvc.
684        virtual void condition ( const vec &val ) {it_error ( "Not implemented!" );};
685
686        //!@}
687
688
689        //! \name Access to attributes
690        //!@{
691
692        const RV& _drv() const {return drv;}
693        void set_drv ( const RV &rv ) {drv=rv;}
694        void set_rv ( const RV &rv ) {const_cast<epdf&> ( posterior() ).set_rv ( rv );}
695        double _ll() const {return ll;}
696        void set_evalll ( bool evl0 ) {evalll=evl0;}
697        virtual const epdf& posterior() const =0;
698        virtual const epdf* _e() const =0;
699        //!@}
700
701        //! \name Logging of results
702        //!@{
703
704        //! Set boolean options from a string recognized are: "logbounds,logll"
705        virtual void set_options ( const string &opt ) {
706                LFlags(0)=1;
707                if ( opt.find ( "logbounds" ) !=string::npos ) {LFlags(1)=1; LFlags(2)=1;}
708                if ( opt.find ( "logll" ) !=string::npos ) {LFlags(3)=1;}
709        }
710        //! IDs of storages in loggers 4:[1=mean,2=lb,3=ub,4=ll]
711        ivec LIDs;
712
713        //! Flags for logging - same size as LIDs, each entry correspond to the same in LIDs
714        ivec LFlags;
715        //! Add all logged variables to a logger
716        virtual void log_add ( logger &L, const string &name="" ) {
717                // internal
718                RV r;
719                if ( posterior().isnamed() ) {r=posterior()._rv();}
720                else{r=RV ( "est", posterior().dimension() );};
721
722                // Add mean value
723                if (LFlags(0)) LIDs ( 0 ) =L.add ( r,name );
724                if (LFlags(1)) LIDs ( 1 ) =L.add ( r,name+"_lb" );
725                if (LFlags(2)) LIDs ( 2 ) =L.add ( r,name+"_ub" );
726                if (LFlags(3)) LIDs ( 3 ) =L.add ( RV("ll",1,0),r.name(0)+name ); //TODO: "local" RV
727        }
728        virtual void logit ( logger &L ) {
729                L.logit ( LIDs ( 0 ), posterior().mean() );
730                if ( LFlags(1) || LFlags(2)) { //if one of them is off, its LID==-1 and will not be stored
731                        vec ub,lb;
732                        posterior().qbounds ( lb,ub );
733                        L.logit ( LIDs ( 1 ), lb ); 
734                        L.logit ( LIDs ( 2 ), ub );
735                }
736                if (LFlags(3)) L.logit ( LIDs ( 3 ), ll );
737        }
738        //!@}
739};
740
741}; //namespace
742#endif // BM_H
Note: See TracBrowser for help on using the browser.