root/library/bdm/base/bdmbase.h @ 477

Revision 477, 25.9 kB (checked in by mido, 15 years ago)

panove, vite, jak jsem peclivej na upravu kodu.. snad se vam bude libit:) konfigurace je v souboru /system/astylerc

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