root/bdm/stat/libBM.h @ 339

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

pridani metod souvisejicich s UserInfo? problematikou do tridy bdmroot

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