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

Revision 895, 33.7 kB (checked in by smidl, 14 years ago)

get rid of Yrv in DS

  • Property svn:eol-style set to native
Line 
1/*!
2  \file
3  \brief Basic structures of probability calculus: random variables, probability densities, Bayes rule
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
29//! Structure of RV, i.e. RVs expanded into a flat list of IDs, used for debugging.
30class str {
31public:
32        //! vector id ids (non-unique!)
33        ivec ids;
34        //! vector of times
35        ivec times;
36        //!Default constructor
37        str ( ivec ids0, ivec times0 ) : ids ( ids0 ), times ( times0 ) {
38                bdm_assert ( times0.length() == ids0.length(), "Incompatible input" );
39        };
40};
41
42/*!
43* \brief Class representing variables, most often random variables
44
45The 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.
46
47The class is implemented using global variables to assure uniqueness of description:
48
49 In is a vector
50\dot
51digraph datalink {
52rankdir=LR;
53subgraph cluster0 {
54node [shape=record];
55label = "MAP \n std::map<string,int>";
56map [label="{{\"a\"| \"b\" | \"c\"} | {<3> 3 |<1> 1|<2> 2}}"];
57color = "white"
58}
59subgraph cluster1{
60node [shape=record];
61label = "NAMES";
62names [label="{<1> \"b\" | <2> \"c\" | <3>\"a\" }"];
63color = "white"
64}
65subgraph cluster2{
66node [shape=record];
67label = "SIZES";
68labelloc = b;
69sizes [label="{<1>1 |<2> 4 |<3> 1}"];
70color = "white"
71}
72map:1 -> names:1;
73map:1 -> sizes:1;
74map:3 -> names:3;
75map:3 -> sizes:3;
76}
77\enddot
78*/
79
80class RV : public root {
81private:
82        typedef std::map<string, int> str2int_map;
83
84        //! Internal global variable storing sizes of RVs
85        static ivec SIZES;
86        //! Internal global variable storing names of RVs
87        static Array<string> NAMES;
88
89        //! TODO
90        const static int BUFFER_STEP;
91
92        //! TODO
93        static str2int_map MAP;
94
95public:
96
97protected:
98        //! size of the data vector
99        int dsize;
100        //! number of individual rvs
101        int len;
102        //! Vector of unique IDs
103        ivec ids;
104        //! Vector of shifts from current time
105        ivec times;
106
107private:
108        enum enum_dummy {dummy};
109
110        //! auxiliary function used in constructor
111        void init( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times );
112
113        //! auxiliary function assigning unique integer index related to the passed name and size of the random variable
114        int assign_id( const string &name, int size );
115
116        //! Private constructor from IDs, potentially dangerous since all ids must be valid!
117        //! dummy is there to prevent confusion with RV(" string");
118        explicit RV ( const ivec &ids0, enum_dummy dum ) : dsize ( 0 ), len ( ids0.length() ), ids ( ids0 ), times ( zeros_i ( ids0.length() ) ) {
119                dsize = countsize();
120        }
121public:
122        //! \name Constructors
123        //!@{
124
125        //! Full constructor
126        RV ( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times ) {
127                init ( in_names, in_sizes, in_times );
128        }
129
130        //! Constructor with times=0
131        RV ( const Array<std::string> &in_names, const ivec &in_sizes ) {
132                init ( in_names, in_sizes, zeros_i ( in_names.length() ) );
133        }
134
135        //! Constructor with sizes=1, times=0
136        RV ( const Array<std::string> &in_names ) {
137                init ( in_names, ones_i ( in_names.length() ), zeros_i ( in_names.length() ) );
138        }
139
140        //! Constructor of empty RV
141        RV() : dsize ( 0 ), len ( 0 ), ids ( 0 ), times ( 0 ) {}
142
143        //! Constructor of a single RV with given id
144        RV ( string name, int sz, int tm = 0 );
145
146        // compiler-generated copy constructor is used
147        //!@}
148
149        //! \name Access functions
150        //!@{
151
152        //! State output, e.g. for debugging.
153        friend std::ostream &operator<< ( std::ostream &os, const RV &rv );
154
155        string to_string() const {
156                ostringstream o;
157                o << *this;
158                return o.str();
159        }
160
161        //! total size of a random variable
162        int _dsize() const {
163                return dsize;
164        }
165
166        //! access function
167        const ivec& _ids() const {
168                return ids;
169        }
170
171        //! Recount size of the corresponding data vector
172        int countsize() const;
173        //! Vector of cumulative sizes of RV
174        ivec cumsizes() const;
175        //! Number of named parts
176        int length() const {
177                return len;
178        }
179        int id ( int at ) const {
180                return ids ( at );
181        }
182        int size ( int at ) const {
183                return SIZES ( ids ( at ) );
184        }
185        int time ( int at ) const {
186                return times ( at );
187        }
188        std::string name ( int at ) const {
189                return NAMES ( ids ( at ) );
190        }
191        //! returns name of a scalar at position scalat, i.e. it can be in the middle of vector name, in that case it adds "_%d" to it
192        std::string scalarname ( int scalat ) const;
193
194        void set_time ( int at, int time0 ) {
195                times ( at ) = time0;
196        }
197        //!@}
198
199        //! \name Algebra on Random Variables
200        //!@{
201
202        //! Find indices of self in another rv, \return ivec of the same size as self.
203        ivec findself ( const RV &rv2 ) const;
204        //! Find indices of self in another rv, ignore time, \return ivec of the same size as self.
205        ivec findself_ids ( const RV &rv2 ) const;
206        //! Compare if \c rv2 is identical to this \c RV
207        bool equal ( const RV &rv2 ) const;
208        //! Add (concat) another variable to the current one, \return true if all rv2 were added, false if rv2 is in conflict
209        bool add ( const RV &rv2 );
210        //! Subtract  another variable from the current one
211        RV subt ( const RV &rv2 ) const;
212        //! Select only variables at indices ind
213        RV subselect ( const ivec &ind ) const;
214
215        //! Select only variables at indices ind
216        RV operator() ( const ivec &ind ) const {
217                return subselect ( ind );
218        }
219
220        //! Select from data vector starting at di1 to di2
221        RV operator() ( int di1, int di2 ) const;
222
223        //! Shift \c time by delta.
224        void t_plus ( int delta );
225        //!@}
226
227        //! @{ \name Time manipulation functions
228        //! returns rvs with time set to 0 and removed duplicates
229        RV remove_time() const {
230                return RV ( unique ( ids ), dummy );
231        }
232        //! create new RV from the current one with time shifted by given value
233        RV copy_t ( int dt ) const {
234                RV tmp = *this;
235                tmp.t_plus ( dt );
236                return tmp;
237        }
238        //! return rvs with expanded delayes and sorted in the order of: \f$ [ rv_{0}, rv_{-1},\ldots  rv_{max_delay}]\f$
239        RV expand_delayes() const;
240        //!@}
241
242        //!\name Relation to vectors
243        //!@{
244
245        //! generate \c str from rv, by expanding sizes
246        str tostr() const;
247        //! when this rv is a part of bigger rv, this function returns indices of self in the data vector of the bigger crv.
248        //! Then, data can be copied via: data_of_this = cdata(ind);
249        ivec dataind ( const RV &crv ) const;
250        //! same as dataind but this time crv should not be complete supperset of rv.
251        ivec dataind_part ( const RV &crv ) const;
252        //! generate mutual indices when copying data between self and crv.
253        //! Data are copied via: data_of_this(selfi) = data_of_rv2(rv2i)
254        void dataind ( const RV &rv2, ivec &selfi, ivec &rv2i ) const;
255        //! Minimum time-offset
256        int mint() const {
257                return times.length() > 0 ? min ( times ) : 0;
258        }
259        //! Minimum time-offset of ids of given RVs
260        int mint ( const RV &rv ) const {
261                bvec belong = zeros_b ( len );
262                for ( int r = 0; r < rv.length(); r++ ) {
263                        belong = belong | ( ids == rv.id ( r ) );
264                }
265                return times.length() > 0 ? min ( get_from_bvec ( times, belong ) ) : 0;
266        }
267        //!@}
268
269        /*! \brief UI for class RV (description of data vectors)
270
271        \code
272        class = 'RV';
273        names = {'a', 'b', 'c', ...};   // UNIQUE IDENTIFIER same names = same variable
274                                                                        // names are also used when storing results
275        --- optional ---
276        sizes = [1, 2, 3, ...];         // size of each name. default = ones()
277                                                                        // if size = -1, it is found out from previous instances of the same name
278        times = [-1, -2, 0, ...];       // time shifts with respect to current time, default = zeros()
279        \endcode
280        */
281        void from_setting ( const Setting &set );
282
283        void to_setting ( Setting &set ) const;
284
285        //! Invalidate all named RVs. Use before initializing any RV instances, with care...
286        static void clear_all();
287        //! function for debugging RV related stuff
288        string show_all();
289
290};
291UIREGISTER ( RV );
292SHAREDPTR ( RV );
293
294//! Concat two random variables
295RV concat ( const RV &rv1, const RV &rv2 );
296
297/*!
298@brief Class for storing results (and semi-results) of an experiment
299
300This 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.
301*/
302class logger : public root {
303protected:
304        //! RVs of all logged variables.
305        Array<RV> entries;
306        //! Names of logged quantities, e.g. names of algorithm variants
307        Array<string> names;
308        //! Root Setting for storing Settings
309        Config setting_conf;
310        //! list of Settings for specific ids
311        Array<Setting*> settings;
312public:
313        //!Default constructor
314        logger ( const string separator0 ) : entries ( 0 ), names ( 0 ), separator ( separator0 ) {}
315
316        //!separator of prefixes of entries
317        //!
318        //! It is a constant string, thus it can be safely declared as public without creating any accessor method
319        const string separator;
320
321
322        //! returns an identifier which will be later needed for calling the \c logit() function
323        //! For empty RV it returns -1, this entry will be ignored by \c logit().
324        virtual int add_vector ( const RV &rv, const string &prefix, const string &name = "" );
325
326        virtual int add_setting ( const string &prefix );
327
328        //! log this vector
329        virtual void log_vector ( int id, const vec &v ) = 0;
330
331        virtual Setting & log_to_setting ( int id ) {
332                return settings ( id )->add ( Setting::TypeGroup );
333        }
334        //! log this double
335        virtual void logit ( int id, const double &d ) = 0;
336
337        //! Shifts storage position for another time step.
338        virtual void step() = 0;
339
340        //! Finalize storing information
341        virtual void finalize() {};
342
343        //! Initialize the storage
344        virtual void init() {};
345};
346
347
348
349//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv
350class fnc : public root {       
351protected:
352        //! Length of the output vector
353        int dimy;
354        //! Length of the input vector
355        int dimc;
356public:
357        //!default constructor
358        fnc() {};
359        //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond
360        virtual vec eval ( const vec &cond ) {
361                return vec ( 0 );
362        };
363
364        //! access function
365        int dimension() const {
366                return dimy;
367        }
368        //! access function
369        int dimensionc() const {
370                return dimc;
371        }
372        void from_setting(const Setting &set){
373                UI::get(dimy, set, "dim", UI::optional);
374                UI::get(dimc, set, "dimc", UI::optional);
375        }
376};
377
378class epdf;
379
380//! Conditional probability density, e.g. modeling \f$ f( x | y) \f$, where \f$ x \f$ is random variable, \c rv, and \f$ y \f$ is conditioning variable, \c rvc.
381class pdf : public root {
382protected:
383        //!dimension of the condition
384        int dimc;
385
386        //! random variable in condition
387        RV rvc;
388
389        //! dimension of random variable
390        int dim;
391
392        //! random variable
393        RV rv;
394
395public:
396        //! \name Constructors
397        //! @{
398
399        pdf() : dimc ( 0 ), rvc(), dim ( 0 ), rv() { }
400
401        pdf ( const pdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), dim ( m.dim ), rv ( m.rv ) { }
402
403        //!@}
404
405        //! \name Matematical operations
406        //!@{
407
408        //! 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
409        virtual vec samplecond ( const vec &cond ) = 0;
410
411        //! 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
412        virtual mat samplecond_mat ( const vec &cond, int N );
413
414        //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently.
415        virtual double evallogcond ( const vec &yt, const vec &cond ) = 0;
416
417        //! Matrix version of evallogcond
418        virtual vec evallogcond_mat ( const mat &Yt, const vec &cond ) {
419                vec v ( Yt.cols() );
420                for ( int i = 0; i < Yt.cols(); i++ ) {
421                        v ( i ) = evallogcond ( Yt.get_col ( i ), cond );
422                }
423                return v;
424        }
425
426        //! Array<vec> version of evallogcond
427        virtual vec evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) {
428                vec v ( Yt.length() );
429                for ( int i = 0; i < Yt.length(); i++ ) {
430                        v ( i ) = evallogcond ( Yt( i ), cond );
431                }
432                return v;
433        }
434
435        //! \name Access to attributes
436        //! @{
437
438        const RV& _rv() const {
439                return rv;
440        }
441        const RV& _rvc() const {
442                return rvc;
443        }
444
445        int dimension() const {
446                return dim;
447        }
448        int dimensionc() {
449                return dimc;
450        }
451
452        //! access function
453        void set_dim ( int d ) {
454                dim = d;
455        }
456        //! access function
457        void set_dimc ( int d ) {
458                dimc = d;
459        }
460        //! Load from structure with elements:
461        //!  \code
462        //! { class = "pdf_offspring",
463        //!   rv = {class="RV", names=(...),}; // RV describing meaning of random variable
464        //!   rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition
465        //!   // elements of offsprings
466        //! }
467        //! \endcode
468        //!@}
469        void from_setting ( const Setting &set );
470
471        void to_setting ( Setting &set ) const;
472        //!@}
473
474        //! \name Connection to other objects
475        //!@{
476        void set_rvc ( const RV &rvc0 ) {
477                rvc = rvc0;
478        }
479        void set_rv ( const RV &rv0 ) {
480                rv = rv0;
481        }
482
483        //! Names of variables stored in RV are considered to be valid only if their size match size of the parameters (dim).
484        bool isnamed() const {
485                return ( dim == rv._dsize() ) && ( dimc == rvc._dsize() );
486        }
487        //!@}
488};
489SHAREDPTR ( pdf );
490
491//! Probability density function with numerical statistics, e.g. posterior density.
492class epdf : public pdf {
493        //! \var log_level_enums logmean
494        //! TODO DOPLNIT       
495       
496        //! \var log_level_enums loglbound
497        //! TODO DOPLNIT
498       
499        //! \var log_level_enums logubound
500        //! TODO DOPLNIT
501       
502        //! \var log_level_enums logfull
503        //! TODO DOPLNIT
504        LOG_LEVEL(epdf,logmean,loglbound,logubound,logfull);
505
506public:
507        /*! \name Constructors
508         Construction of each epdf should support two types of constructors:
509        \li empty constructor,
510        \li copy constructor,
511
512        The following constructors should be supported for convenience:
513        \li constructor followed by calling \c set_parameters() WHICH IS OBSOLETE (TODO)
514        \li constructor accepting random variables calling \c set_rv()
515
516         All internal data structures are constructed as empty. Their values (including sizes) will be
517         set by method \c set_parameters() WHICH IS OBSOLETE (TODO). This way references can be initialized in constructors.
518        @{*/
519        epdf() {};
520        epdf ( const epdf &e ) : pdf ( e ) {};
521       
522       
523        //!@}
524
525        //! \name Matematical Operations
526        //!@{
527
528        //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$
529        virtual vec sample() const = 0;
530
531        //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$  from density \f$ f_x(rv)\f$
532        virtual mat sample_mat ( int N ) const;
533
534        //! Compute log-probability of argument \c val
535        //! In case the argument is out of suport return -Infinity
536        virtual double evallog ( const vec &val ) const = 0;
537       
538        //! Compute log-probability of multiple values argument \c val
539        virtual vec evallog_mat ( const mat &Val ) const;
540
541        //! Compute log-probability of multiple values argument \c val
542        virtual vec evallog_mat ( const Array<vec> &Avec ) const;
543
544        //! Return conditional density on the given RV, the remaining rvs will be in conditioning
545        virtual shared_ptr<pdf> condition ( const RV &rv ) const;
546
547        //! Return marginal density on the given RV, the remainig rvs are intergrated out
548        virtual shared_ptr<epdf> marginal ( const RV &rv ) const;
549
550        virtual vec mean() const = 0;
551
552        //! return expected variance (not covariance!)
553        virtual vec variance() const = 0;
554
555        //! return expected covariance -- default is diag(variance)!!
556        virtual mat covariance() const {return diag(variance());};
557       
558        //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default
559        virtual void qbounds ( vec &lb, vec &ub, double percentage = 0.95 ) const {
560                vec mea = mean();
561                vec std = sqrt ( variance() );
562                lb = mea - 2 * std;
563                ub = mea + 2 * std;
564        };
565        //! Set statistics to match given input epdf. Typically it copies statistics from epdf of the same type and projects those form different types
566        //! \param pdf0 epdf to match
567        //! \param option placeholder for potential options
568        void set_statistics(const epdf *pdf0) NOT_IMPLEMENTED_VOID;
569        //!@}
570
571        //! \name Connection to other classes
572        //! Description of the random quantity via attribute \c rv is optional.
573        //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization
574        //! and \c conditioning \c rv has to be set. NB:
575        //! @{
576
577        //! store values of the epdf on the following levels:
578        //!  #1 mean
579        //!  #2 mean + lower & upper bound
580        void log_register ( logger &L, const string &prefix );
581
582        void log_write() const;
583        //!@}
584
585        //! \name Access to attributes
586        //! @{
587
588        //! Load from structure with elements:
589        //!  \code
590        //! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable
591        //!   // elements of offsprings
592        //! }
593        //! \endcode
594        //!@}
595        void from_setting ( const Setting &set ) {
596                shared_ptr<RV> r = UI::build<RV> ( set, "rv", UI::optional );
597                if ( r ) {
598                        set_rv ( *r );
599                }
600        }
601
602        void to_setting ( Setting &set ) const {
603                // we do not want to store rvc, therfore, pdf::to_setting( set ) is omitted
604                root::to_setting(set);
605
606                UI::save( &rv, set, "rv" );
607        }
608
609        vec samplecond ( const vec &cond ) {
610                return sample();
611        }
612        double evallogcond ( const vec &val, const vec &cond ) {
613                return evallog ( val );
614        }
615};
616SHAREDPTR ( epdf );
617
618//! pdf with internal epdf that is modified by function \c condition
619template <class EPDF>
620class pdf_internal: public pdf {
621protected :
622        //! Internal epdf used for sampling
623        EPDF iepdf;
624public:
625        //! constructor
626        pdf_internal() : pdf(), iepdf() {
627        }
628
629        //! Update \c iepdf so that it represents this pdf conditioned on \c rvc = cond
630        //! This function provides convenient reimplementation in offsprings
631        virtual void condition ( const vec &cond ) = 0;
632
633        //!access function to iepdf
634        EPDF& e() {
635                return iepdf;
636        }
637
638        //! Reimplements samplecond using \c condition()
639        vec samplecond ( const vec &cond );
640        //! Reimplements evallogcond using \c condition()
641        double evallogcond ( const vec &val, const vec &cond );
642        //! Efficient version of evallogcond for matrices
643        virtual vec evallogcond_mat ( const mat &Dt, const vec &cond );
644        //! Efficient version of evallogcond for Array<vec>
645        virtual vec evallogcond_mat ( const Array<vec> &Dt, const vec &cond );
646        //! Efficient version of samplecond
647        virtual mat samplecond_mat ( const vec &cond, int N );
648
649        void validate() {
650                iepdf.validate();
651                if ( rv._dsize() < iepdf._rv()._dsize() ) {
652                        rv = iepdf._rv();
653                };
654                dim = iepdf.dimension();
655        }
656};
657
658/*! \brief DataLink is a connection between two data vectors Up and Down
659
660Up can be longer than Down. Down must be fully present in Up (TODO optional)
661See chart:
662\dot
663digraph datalink {
664  node [shape=record];
665  subgraph cluster0 {
666    label = "Up";
667      up [label="<1>|<2>|<3>|<4>|<5>"];
668    color = "white"
669}
670  subgraph cluster1{
671    label = "Down";
672    labelloc = b;
673      down [label="<1>|<2>|<3>"];
674    color = "white"
675}
676    up:1 -> down:1;
677    up:3 -> down:2;
678    up:5 -> down:3;
679}
680\enddot
681
682*/
683class datalink {
684protected:
685        //! Remember how long val should be
686        int downsize;
687
688        //! Remember how long val of "Up" should be
689        int upsize;
690
691        //! val-to-val link, indices of the upper val
692        ivec v2v_up;
693
694public:
695        //! Constructor
696        datalink() : downsize ( 0 ), upsize ( 0 ) { }
697
698        //! Convenience constructor
699        datalink ( const RV &rv, const RV &rv_up ) {
700                set_connection ( rv, rv_up );
701        }
702
703        //! set connection, rv must be fully present in rv_up
704        virtual void set_connection ( const RV &rv, const RV &rv_up );
705
706        //! set connection using indices
707        virtual void set_connection ( int ds, int us, const ivec &upind );
708
709        //! Get val for myself from val of "Up"
710        vec pushdown ( const vec &val_up ) {
711                vec tmp ( downsize );
712                filldown ( val_up, tmp );
713                return tmp;
714        }
715        //! Get val for vector val_down from val of "Up"
716        virtual void filldown ( const vec &val_up, vec &val_down ) {
717                bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" );
718                val_down = val_up ( v2v_up );
719        }
720        //! Fill val of "Up" by my pieces
721        virtual void pushup ( vec &val_up, const vec &val ) {
722                bdm_assert_debug ( downsize == val.length(), "Wrong val" );
723                bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" );
724                set_subvector ( val_up, v2v_up, val );
725        }
726        //! access functions
727        int _upsize() {
728                return upsize;
729        }
730        //! access functions
731        int _downsize() {
732                return downsize;
733        }
734        //! for future use
735        virtual ~datalink() {}
736};
737
738/*! Extension of datalink to fill only part of Down
739*/
740class datalink_part : public datalink {
741protected:
742        //! indeces of values in vector downsize
743        ivec v2v_down;
744public:
745        void set_connection ( const RV &rv, const RV &rv_up );
746        //! Get val for vector val_down from val of "Up"
747        void filldown ( const vec &val_up, vec &val_down ) {
748                set_subvector ( val_down, v2v_down, val_up ( v2v_up ) );
749        }
750};
751
752/*! \brief Datalink that buffers delayed values - do not forget to call step()
753
754Up is current data, Down is their subset with possibly delayed values
755*/
756class datalink_buffered: public datalink_part {
757protected:
758        //! History, ordered as \f$[Up_{t-1},Up_{t-2}, \ldots]\f$
759        vec history;
760        //! rv of the history
761        RV Hrv;
762        //! h2v : indeces in down
763        ivec h2v_down;
764        //! h2v : indeces in history
765        ivec h2v_hist;
766        //! v2h: indeces of up too be pushed to h
767        ivec v2h_up;
768public:
769
770        datalink_buffered() : datalink_part(), history ( 0 ), h2v_down ( 0 ), h2v_hist ( 0 ) {};
771        //! push current data to history
772        void store_data ( const vec &val_up ) {
773                if ( v2h_up.length() > 0 ) {
774                        history.shift_right ( 0, v2h_up.length() );
775                        history.set_subvector ( 0, val_up ( v2h_up ) );
776                }
777        }
778        //! Get val for myself from val of "Up"
779        vec pushdown ( const vec &val_up ) {
780                vec tmp ( downsize );
781                filldown ( val_up, tmp );
782                return tmp;
783        }
784
785        void filldown ( const vec &val_up, vec &val_down ) {
786                bdm_assert_debug ( val_down.length() >= downsize, "short val_down" );
787
788                set_subvector ( val_down, v2v_down, val_up ( v2v_up ) ); // copy direct values
789                set_subvector ( val_down, h2v_down, history ( h2v_hist ) ); // copy delayed values
790        }
791
792        void set_connection ( const RV &rv, const RV &rv_up );
793       
794        //! set history of variable given by \c rv1 to values of \c hist.
795        void set_history ( const RV& rv1, const vec &hist0 );
796};
797
798//! buffered datalink from 2 vectors to 1
799class datalink_2to1_buffered {
800protected:
801        //! link 1st vector to down
802        datalink_buffered dl1;
803        //! link 2nd vector to down
804        datalink_buffered dl2;
805public:
806        //! set connection between RVs
807        void set_connection ( const RV &rv, const RV &rv_up1, const RV &rv_up2 ) {
808                dl1.set_connection ( rv, rv_up1 );
809                dl2.set_connection ( rv, rv_up2 );
810        }
811        //! fill values of down from the values of the two up vectors
812        void filldown ( const vec &val1, const vec &val2, vec &val_down ) {
813                bdm_assert_debug ( val_down.length() >= dl1._downsize() + dl2._downsize(), "short val_down" );
814                dl1.filldown ( val1, val_down );
815                dl2.filldown ( val2, val_down );
816        }
817        //! update buffer
818        void step ( const vec &dt, const vec &ut ) {
819                dl1.store_data ( dt );
820                dl2.store_data ( ut );
821        }
822};
823
824
825
826//! Data link with a condition.
827class datalink_m2e: public datalink {
828protected:
829        //! Remember how long cond should be
830        int condsize;
831
832        //!upper_val-to-local_cond link, indices of the upper val
833        ivec v2c_up;
834
835        //!upper_val-to-local_cond link, indices of the local cond
836        ivec v2c_lo;
837
838public:
839        //! Constructor
840        datalink_m2e() : condsize ( 0 ) { }
841
842        //! Set connection between vectors
843        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up );
844
845        //!Construct condition
846        vec get_cond ( const vec &val_up );
847
848        //! Copy corresponding values to Up.condition
849        void pushup_cond ( vec &val_up, const vec &val, const vec &cond );
850};
851
852//!DataLink is a connection between pdf and its superordinate (Up)
853//! This class links
854class datalink_m2m: public datalink_m2e {
855protected:
856        //!cond-to-cond link, indices of the upper cond
857        ivec c2c_up;
858        //!cond-to-cond link, indices of the local cond
859        ivec c2c_lo;
860
861public:
862        //! Constructor
863        datalink_m2m() {};
864        //! Set connection between the vectors
865        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) {
866                datalink_m2e::set_connection ( rv, rvc, rv_up );
867                //establish c2c connection
868                rvc.dataind ( rvc_up, c2c_lo, c2c_up );
869//              bdm_assert_debug ( c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given" );
870        }
871
872        //! Get cond for myself from val and cond of "Up"
873        vec get_cond ( const vec &val_up, const vec &cond_up ) {
874                vec tmp ( condsize );
875                fill_cond ( val_up, cond_up, tmp );
876                return tmp;
877        }
878        //! fill condition
879        void fill_cond ( const vec &val_up, const vec &cond_up, vec& cond_out ) {
880                bdm_assert_debug ( cond_out.length() >= condsize, "dl.fill_cond: cond_out is too small" );
881                set_subvector ( cond_out, v2c_lo, val_up ( v2c_up ) );
882                set_subvector ( cond_out, c2c_lo, cond_up ( c2c_up ) );
883        }
884        //! Fill
885
886};
887
888
889//! \brief Combines RVs from a list of pdfs to a single one.
890RV get_composite_rv ( const Array<shared_ptr<pdf> > &pdfs, bool checkoverlap = false );
891
892/*! \brief Abstract class for discrete-time sources of data.
893
894The class abstracts operations of:
895\li  data aquisition,
896\li  data-preprocessing, such as  scaling of data,
897\li  data resampling from the task of estimation and control.
898Moreover, for controlled systems, it is able to receive the desired control action and perform it in the next step. (Or as soon as possible).
899
900The DataSource has three main data interaction structures:
901\li input, \f$ u_t \f$,
902\li output \f$ y_t \f$,
903\li data, \f$ d_t=[y_t,u_t, \ldots ]\f$ a collection of all inputs and outputs and possibly some internal variables too.
904
905*/
906
907class DS : public root {
908        //! \var log_level_enums dt
909        //! TODO DOPLNIT
910        LOG_LEVEL(DS, dt);
911
912protected:
913        //! size of data returned by \c getdata()
914        int dtsize;
915        //! size of data
916        int utsize;
917        //!Description of data returned by \c getdata().
918        RV Drv;
919        //!Description of data witten by by \c write().
920        RV Urv; //
921public:
922        //! default constructors
923        DS() : dtsize ( 0 ), utsize ( 0 ), Drv(), Urv(){
924                log_level[dt] = true;
925        };
926
927        //! Returns maximum number of provided data, by default it is set to maximum allowed length, shorter DS should overload this method! See, MemDS.max_length().
928        virtual int max_length() {
929                return std::numeric_limits< int >::max();
930        }
931        //! Returns full vector of observed data=[output, input]
932        virtual void getdata ( vec &dt ) const = 0;
933
934        //! Returns data records at indeces. Default is inefficent.
935        virtual void getdata ( vec &dt, const ivec &indeces ) {
936                vec tmp(dtsize);
937                getdata(tmp);
938                dt = tmp(indeces);
939        };
940
941        //! Accepts action variable and schedule it for application.   
942        virtual void write ( const vec &ut ) NOT_IMPLEMENTED_VOID;
943
944        //! Accepts action variables at specific indeces
945        virtual void write ( const vec &ut, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
946
947        //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system.
948        virtual void step() = 0;
949
950        //! Register DS for logging into logger L
951        virtual void log_register ( logger &L,  const string &prefix );
952        //! Register DS for logging into logger L
953        virtual void log_write ( ) const;
954        //!access function
955        virtual const RV& _drv() const {
956                return Drv;
957        }
958        //!access function
959        const RV& _urv() const {
960                return Urv;
961        }
962        //! set random variables
963        virtual void set_drv ( const  RV &drv, const RV &urv) {
964                Drv = drv;
965                Urv = urv;
966        }
967};
968
969/*! \brief Bayesian Model of a system, i.e. all uncertainty is modeled by probabilities.
970
971This object represents exact or approximate evaluation of the Bayes rule:
972\f[
973f(\theta_t | y_1,\ldots,y_t, u_1,\ldots,u_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})}
974\f]
975where:
976 * \f$ y_t \f$ is the variable
977Access to the resulting posterior density is via function \c posterior().
978
979As a "side-effect" it also evaluates log-likelihood of the data, which can be accessed via function _ll().
980It can also evaluate predictors of future values of \f$y_t\f$, see functions epredictor() and predictor().
981
982Alternatively, it can evaluate posterior density with rvc replaced by the given values, \f$ c_t \f$:
983\f[
984f(\theta_t | c_t, d_1,\ldots,d_t) \propto  f(y_t,\theta_t|c_t,\cdot, d_1,\ldots,d_{t-1})
985\f]
986
987*/
988
989class BM : public root {
990        //! \var log_level_enums logfull
991        //! TODO DOPLNIT
992
993        //! \var log_level_enums logevidence
994        //! TODO DOPLNIT
995       
996        //! \var log_level_enums logbounds
997        //! TODO DOPLNIT       
998        LOG_LEVEL(BM,logfull,logevidence,logbounds);
999
1000protected:
1001        //! Random variable of the data (optional)
1002        RV yrv;
1003        //! size of the data record
1004        int dimy;
1005        //! Name of extension variable
1006        RV rvc;
1007        //! size of the conditioning vector
1008        int dimc;
1009
1010        //!Logarithm of marginalized data likelihood.
1011        double ll;
1012        //!  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.
1013        bool evalll;
1014
1015public:
1016        //! \name Constructors
1017        //! @{
1018
1019        BM() : yrv(), dimy ( 0 ), rvc(), dimc ( 0 ), ll ( 0 ), evalll ( true ) { };
1020        //      BM ( const BM &B ) :  yrv ( B.yrv ), dimy(B.dimy), rvc ( B.rvc ),dimc(B.dimc), ll ( B.ll ), evalll ( B.evalll ) {}
1021        //! \brief Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually!
1022        //! Prototype: \code BM* _copy() const {return new BM(*this);} \endcode
1023        virtual BM* _copy() const NOT_IMPLEMENTED(NULL);
1024        //!@}
1025
1026        //! \name Mathematical operations
1027        //!@{
1028
1029        /*! \brief Incremental Bayes rule
1030        @param dt vector of input data
1031        */
1032        virtual void bayes ( const vec &yt, const vec &cond = empty_vec ) = 0;
1033        //! Batch Bayes rule (columns of Dt are observations)
1034        virtual void bayes_batch ( const mat &Dt, const vec &cond = empty_vec );
1035        //! Batch Bayes rule (columns of Dt are observations, columns of Cond are conditions)
1036        virtual void bayes_batch ( const mat &Dt, const mat &Cond );
1037        //! Evaluates predictive log-likelihood of the given data record
1038        //! I.e. marginal likelihood of the data with the posterior integrated out.
1039        //! This function evaluates only \f$ y_t \f$, condition is assumed to be the last used in bayes().
1040        //! See bdm::BM::predictor for conditional version.
1041        virtual double logpred ( const vec &yt ) const NOT_IMPLEMENTED(0.0);
1042
1043        //! Matrix version of logpred
1044        vec logpred_mat ( const mat &Yt ) const {
1045                vec tmp ( Yt.cols() );
1046                for ( int i = 0; i < Yt.cols(); i++ ) {
1047                        tmp ( i ) = logpred ( Yt.get_col ( i ) );
1048                }
1049                return tmp;
1050        }
1051
1052        //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$
1053        virtual epdf* epredictor() const NOT_IMPLEMENTED(NULL);
1054
1055        //!Constructs conditional density of 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) \f$
1056        virtual pdf* predictor() const NOT_IMPLEMENTED(NULL);
1057
1058        //!@}
1059
1060
1061        //! \name Access to attributes
1062        //!@{
1063        //! access function
1064        const RV& _rvc() const {
1065                return rvc;
1066        }
1067        //! access function
1068        int dimensionc() const {
1069                return dimc;
1070        }
1071        //! access function
1072        int dimensiony() const {
1073                return dimy;
1074        }
1075        //! access function
1076        int dimension() const {
1077                return posterior().dimension();
1078        }
1079        //! access function
1080        const RV& _rv() const {
1081                return posterior()._rv();
1082        }
1083        //! access function
1084        const RV& _yrv() const {
1085                return yrv;
1086        }
1087        //! access function
1088        void set_yrv ( const RV &rv ) {
1089                yrv = rv;
1090        }
1091        //! access function
1092        void set_rvc ( const RV &rv ) {
1093                rvc = rv;
1094        }
1095        //! access to rv of the posterior
1096        void set_rv ( const RV &rv ) {
1097                const_cast<epdf&> ( posterior() ).set_rv ( rv );
1098        }
1099        //! access function
1100        void set_dim ( int dim ) {
1101                const_cast<epdf&> ( posterior() ).set_dim ( dim );
1102        }
1103        //! return internal log-likelihood of the last data vector
1104        double _ll() const {
1105                return ll;
1106        }
1107        //! switch evaluation of log-likelihood on/off
1108        void set_evalll ( bool evl0 ) {
1109                evalll = evl0;
1110        }
1111        //! return posterior density
1112        virtual const epdf& posterior() const = 0;
1113       
1114        epdf& prior() {return const_cast<epdf&>(posterior());}
1115        //! set prior density -- same as posterior but writable
1116        virtual void set_prior(const epdf *pdf0) NOT_IMPLEMENTED_VOID;
1117       
1118        //!@}
1119
1120        //! \name Logging of results
1121        //!@{
1122
1123        //! Add all logged variables to a logger
1124        //! Log levels two digits: xy where
1125        //!  * y = 0/1 log-likelihood is to be logged
1126        //!  * x = level of the posterior (typically 0/1/2 for nothing/mean/bounds)
1127        virtual void log_register ( logger &L, const string &prefix = "" );
1128
1129        //! Save results to the given logger, details of what is stored is configured by \c LIDs and \c options
1130        virtual void log_write ( ) const;
1131
1132        //!@}
1133        void from_setting ( const Setting &set ) {
1134                shared_ptr<RV> r = UI::build<RV> ( set, "yrv", UI::optional );
1135                if ( r ) {
1136                        set_yrv ( *r );
1137                }
1138                shared_ptr<RV> r2 = UI::build<RV> ( set, "rvc", UI::optional );
1139                if ( r2 ) {
1140                        rvc =   *r2;
1141                }
1142                shared_ptr<RV> r3 = UI::build<RV> ( set, "rv", UI::optional );
1143                if ( r3 ) {
1144                        set_rv ( *r3 );
1145                }
1146
1147                UI::get ( log_level, set, "log_level", UI::optional );
1148        }
1149
1150        void to_setting ( Setting &set ) const {
1151                root::to_setting( set );
1152                UI::save( &yrv, set, "yrv" );
1153                UI::save( &rvc, set, "rvc" );           
1154                UI::save( &posterior()._rv(), set, "rv" );
1155                UI::save( log_level, set );
1156        }
1157
1158        void validate()
1159        {
1160                if ( log_level[logfull] ) {
1161                        const_cast<epdf&> ( posterior() ).log_level[epdf::logfull] = true;
1162                } else {
1163                        if ( log_level[logbounds] ) {
1164                                const_cast<epdf&> ( posterior() ).log_level[epdf::loglbound] = true;
1165                        } else {
1166                                const_cast<epdf&> ( posterior() ).log_level[epdf::logmean] = true;;
1167                        }
1168                        if ( log_level[logevidence] ) {
1169                        }
1170                }
1171        }
1172};
1173
1174//! array of pointers to epdf
1175typedef Array<shared_ptr<epdf> > epdf_array;
1176//! array of pointers to pdf
1177typedef Array<shared_ptr<pdf> > pdf_array;
1178
1179template<class EPDF>
1180vec pdf_internal<EPDF>::samplecond ( const vec &cond ) {
1181        condition ( cond );
1182        vec temp = iepdf.sample();
1183        return temp;
1184}
1185
1186template<class EPDF>
1187mat pdf_internal<EPDF>::samplecond_mat ( const vec &cond, int N ) {
1188        condition ( cond );
1189        mat temp ( dimension(), N );
1190        vec smp ( dimension() );
1191        for ( int i = 0; i < N; i++ ) {
1192                smp = iepdf.sample();
1193                temp.set_col ( i, smp );
1194        }
1195
1196        return temp;
1197}
1198
1199template<class EPDF>
1200double pdf_internal<EPDF>::evallogcond ( const vec &yt, const vec &cond ) {
1201        double tmp;
1202        condition ( cond );
1203        tmp = iepdf.evallog ( yt );
1204        return tmp;
1205}
1206
1207template<class EPDF>
1208vec pdf_internal<EPDF>::evallogcond_mat ( const mat &Yt, const vec &cond ) {
1209        condition ( cond );
1210        return iepdf.evallog_mat ( Yt );
1211}
1212
1213template<class EPDF>
1214vec pdf_internal<EPDF>::evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) {
1215        condition ( cond );
1216        return iepdf.evallog_mat ( Yt );
1217}
1218
1219}; //namespace
1220#endif // BDMBASE_H
Note: See TracBrowser for help on using the browser.