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

Revision 850, 32.8 kB (checked in by smidl, 14 years ago)

changes in Loggers!

  • 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        //!separator of prefixes of entries
309        const string separator;
310        //! Root Setting for storing Settings
311        Config setting_conf;
312        //! list of Settings for specific ids
313        Array<Setting*> settings;
314public:
315        //!Default constructor
316        logger ( const string separator0 ) : entries ( 0 ), names ( 0 ), separator ( separator0 ) {}
317
318        //! returns an identifier which will be later needed for calling the \c logit() function
319        //! For empty RV it returns -1, this entry will be ignored by \c logit().
320        virtual int add_vector ( const RV &rv, string prefix = "" );
321
322        virtual int add_setting ( const string &prefix );
323
324        //! log this vector
325        virtual void log_vector ( int id, const vec &v ) = 0;
326
327        virtual Setting & log_to_setting ( int id ) {
328                return settings ( id )->add ( Setting::TypeGroup );
329        }
330        //! log this double
331        virtual void logit ( int id, const double &d ) = 0;
332
333        //! Shifts storage position for another time step.
334        virtual void step() = 0;
335
336        //! Finalize storing information
337        virtual void finalize() {};
338
339        //! Initialize the storage
340        virtual void init() {};
341
342        //!separator of prefixes for this logger
343        const string& prefix_sep() {
344                return separator;
345        }
346};
347
348
349
350//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv
351class fnc : public root {       
352protected:
353        //! Length of the output vector
354        int dimy;
355        //! Length of the input vector
356        int dimc;
357public:
358        //!default constructor
359        fnc() {};
360        //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond
361        virtual vec eval ( const vec &cond ) {
362                return vec ( 0 );
363        };
364
365        //! access function
366        int dimension() const {
367                return dimy;
368        }
369        //! access function
370        int dimensionc() const {
371                return dimc;
372        }
373        void from_setting(const Setting &set){
374                UI::get(dimy, set, "dim", UI::optional);
375                UI::get(dimc, set, "dimc", UI::optional);
376        }
377};
378
379class epdf;
380
381//! 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.
382class pdf : public root {
383protected:
384        //!dimension of the condition
385        int dimc;
386
387        //! random variable in condition
388        RV rvc;
389
390        //! dimension of random variable
391        int dim;
392
393        //! random variable
394        RV rv;
395
396public:
397        //! \name Constructors
398        //! @{
399
400        pdf() : dimc ( 0 ), rvc(), dim ( 0 ), rv() { }
401
402        pdf ( const pdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), dim ( m.dim ), rv ( m.rv ) { }
403
404        //!@}
405
406        //! \name Matematical operations
407        //!@{
408
409        //! 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
410        virtual vec samplecond ( const vec &cond ) = 0;
411
412        //! 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
413        virtual mat samplecond_mat ( const vec &cond, int N );
414
415        //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently.
416        virtual double evallogcond ( const vec &yt, const vec &cond ) = 0;
417
418        //! Matrix version of evallogcond
419        virtual vec evallogcond_mat ( const mat &Yt, const vec &cond ) {
420                vec v ( Yt.cols() );
421                for ( int i = 0; i < Yt.cols(); i++ ) {
422                        v ( i ) = evallogcond ( Yt.get_col ( i ), cond );
423                }
424                return v;
425        }
426
427        //! Array<vec> version of evallogcond
428        virtual vec evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) {
429                vec v ( Yt.length() );
430                for ( int i = 0; i < Yt.length(); i++ ) {
431                        v ( i ) = evallogcond ( Yt( i ), cond );
432                }
433                return v;
434        }
435
436        //! \name Access to attributes
437        //! @{
438
439        const RV& _rv() const {
440                return rv;
441        }
442        const RV& _rvc() const {
443                return rvc;
444        }
445
446        int dimension() const {
447                return dim;
448        }
449        int dimensionc() {
450                return dimc;
451        }
452
453        //! access function
454        void set_dim ( int d ) {
455                dim = d;
456        }
457        //! access function
458        void set_dimc ( int d ) {
459                dimc = d;
460        }
461        //! Load from structure with elements:
462        //!  \code
463        //! { class = "pdf_offspring",
464        //!   rv = {class="RV", names=(...),}; // RV describing meaning of random variable
465        //!   rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition
466        //!   // elements of offsprings
467        //! }
468        //! \endcode
469        //!@}
470        void from_setting ( const Setting &set );
471
472        void to_setting ( Setting &set ) const;
473        //!@}
474
475        //! \name Connection to other objects
476        //!@{
477        void set_rvc ( const RV &rvc0 ) {
478                rvc = rvc0;
479        }
480        void set_rv ( const RV &rv0 ) {
481                rv = rv0;
482        }
483
484        //! Names of variables stored in RV are considered to be valid only if their size match size of the parameters (dim).
485        bool isnamed() const {
486                return ( dim == rv._dsize() ) && ( dimc == rvc._dsize() );
487        }
488        //!@}
489};
490SHAREDPTR ( pdf );
491
492//! Probability density function with numerical statistics, e.g. posterior density.
493class epdf : public pdf {
494        LOG_LEVEL(epdf,jedna,dva,tri,deset);
495
496public:
497        /*! \name Constructors
498         Construction of each epdf should support two types of constructors:
499        \li empty constructor,
500        \li copy constructor,
501
502        The following constructors should be supported for convenience:
503        \li constructor followed by calling \c set_parameters()
504        \li constructor accepting random variables calling \c set_rv()
505
506         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.
507        @{*/
508        epdf() {};
509        epdf ( const epdf &e ) : pdf ( e ) {};
510       
511       
512        //!@}
513
514        //! \name Matematical Operations
515        //!@{
516
517        //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$
518        virtual vec sample() const = 0;
519
520        //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$  from density \f$ f_x(rv)\f$
521        virtual mat sample_mat ( int N ) const;
522
523        //! Compute log-probability of argument \c val
524        //! In case the argument is out of suport return -Infinity
525        virtual double evallog ( const vec &val ) const = 0;
526       
527        //! Compute log-probability of multiple values argument \c val
528        virtual vec evallog_mat ( const mat &Val ) const;
529
530        //! Compute log-probability of multiple values argument \c val
531        virtual vec evallog_mat ( const Array<vec> &Avec ) const;
532
533        //! Return conditional density on the given RV, the remaining rvs will be in conditioning
534        virtual shared_ptr<pdf> condition ( const RV &rv ) const;
535
536        //! Return marginal density on the given RV, the remainig rvs are intergrated out
537        virtual shared_ptr<epdf> marginal ( const RV &rv ) const;
538
539        virtual vec mean() const = 0;
540
541        //! return expected variance (not covariance!)
542        virtual vec variance() const = 0;
543
544        //! return expected covariance -- default is diag(variance)!!
545        virtual mat covariance() const {return diag(variance());};
546       
547        //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default
548        virtual void qbounds ( vec &lb, vec &ub, double percentage = 0.95 ) const {
549                vec mea = mean();
550                vec std = sqrt ( variance() );
551                lb = mea - 2 * std;
552                ub = mea + 2 * std;
553        };
554        //!@}
555
556        //! \name Connection to other classes
557        //! Description of the random quantity via attribute \c rv is optional.
558        //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization
559        //! and \c conditioning \c rv has to be set. NB:
560        //! @{
561
562        //! store values of the epdf on the following levels:
563        //!  #1 mean
564        //!  #2 mean + lower & upper bound
565        void log_register ( logger &L, const string &prefix );
566
567        void log_write() const;
568        //!@}
569
570        //! \name Access to attributes
571        //! @{
572
573        //! Load from structure with elements:
574        //!  \code
575        //! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable
576        //!   // elements of offsprings
577        //! }
578        //! \endcode
579        //!@}
580        void from_setting ( const Setting &set ) {
581                shared_ptr<RV> r = UI::build<RV> ( set, "rv", UI::optional );
582                if ( r ) {
583                        set_rv ( *r );
584                }
585        }
586
587        void to_setting ( Setting &set ) const {
588                // we do not want to store rvc, therfore, pdf::to_setting( set ) is omitted
589                root::to_setting(set);
590
591                UI::save( &rv, set, "rv" );
592        }
593
594        vec samplecond ( const vec &cond ) {
595                return sample();
596        }
597        double evallogcond ( const vec &val, const vec &cond ) {
598                return evallog ( val );
599        }
600};
601SHAREDPTR ( epdf );
602
603//! pdf with internal epdf that is modified by function \c condition
604template <class EPDF>
605class pdf_internal: public pdf {
606protected :
607        //! Internal epdf used for sampling
608        EPDF iepdf;
609public:
610        //! constructor
611        pdf_internal() : pdf(), iepdf() {
612        }
613
614        //! Update \c iepdf so that it represents this pdf conditioned on \c rvc = cond
615        //! This function provides convenient reimplementation in offsprings
616        virtual void condition ( const vec &cond ) = 0;
617
618        //!access function to iepdf
619        EPDF& e() {
620                return iepdf;
621        }
622
623        //! Reimplements samplecond using \c condition()
624        vec samplecond ( const vec &cond );
625        //! Reimplements evallogcond using \c condition()
626        double evallogcond ( const vec &val, const vec &cond );
627        //! Efficient version of evallogcond for matrices
628        virtual vec evallogcond_mat ( const mat &Dt, const vec &cond );
629        //! Efficient version of evallogcond for Array<vec>
630        virtual vec evallogcond_mat ( const Array<vec> &Dt, const vec &cond );
631        //! Efficient version of samplecond
632        virtual mat samplecond_mat ( const vec &cond, int N );
633
634        void validate() {
635                iepdf.validate();
636                if ( rv._dsize() < iepdf._rv()._dsize() ) {
637                        rv = iepdf._rv();
638                };
639                dim = iepdf.dimension();
640        }
641};
642
643/*! \brief DataLink is a connection between two data vectors Up and Down
644
645Up can be longer than Down. Down must be fully present in Up (TODO optional)
646See chart:
647\dot
648digraph datalink {
649  node [shape=record];
650  subgraph cluster0 {
651    label = "Up";
652      up [label="<1>|<2>|<3>|<4>|<5>"];
653    color = "white"
654}
655  subgraph cluster1{
656    label = "Down";
657    labelloc = b;
658      down [label="<1>|<2>|<3>"];
659    color = "white"
660}
661    up:1 -> down:1;
662    up:3 -> down:2;
663    up:5 -> down:3;
664}
665\enddot
666
667*/
668class datalink {
669protected:
670        //! Remember how long val should be
671        int downsize;
672
673        //! Remember how long val of "Up" should be
674        int upsize;
675
676        //! val-to-val link, indices of the upper val
677        ivec v2v_up;
678
679public:
680        //! Constructor
681        datalink() : downsize ( 0 ), upsize ( 0 ) { }
682
683        //! Convenience constructor
684        datalink ( const RV &rv, const RV &rv_up ) {
685                set_connection ( rv, rv_up );
686        }
687
688        //! set connection, rv must be fully present in rv_up
689        virtual void set_connection ( const RV &rv, const RV &rv_up );
690
691        //! set connection using indices
692        virtual void set_connection ( int ds, int us, const ivec &upind );
693
694        //! Get val for myself from val of "Up"
695        vec pushdown ( const vec &val_up ) {
696                vec tmp ( downsize );
697                filldown ( val_up, tmp );
698                return tmp;
699        }
700        //! Get val for vector val_down from val of "Up"
701        virtual void filldown ( const vec &val_up, vec &val_down ) {
702                bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" );
703                val_down = val_up ( v2v_up );
704        }
705        //! Fill val of "Up" by my pieces
706        virtual void pushup ( vec &val_up, const vec &val ) {
707                bdm_assert_debug ( downsize == val.length(), "Wrong val" );
708                bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" );
709                set_subvector ( val_up, v2v_up, val );
710        }
711        //! access functions
712        int _upsize() {
713                return upsize;
714        }
715        //! access functions
716        int _downsize() {
717                return downsize;
718        }
719        //! for future use
720        virtual ~datalink() {}
721};
722
723/*! Extension of datalink to fill only part of Down
724*/
725class datalink_part : public datalink {
726protected:
727        //! indeces of values in vector downsize
728        ivec v2v_down;
729public:
730        void set_connection ( const RV &rv, const RV &rv_up );
731        //! Get val for vector val_down from val of "Up"
732        void filldown ( const vec &val_up, vec &val_down ) {
733                set_subvector ( val_down, v2v_down, val_up ( v2v_up ) );
734        }
735};
736
737/*! \brief Datalink that buffers delayed values - do not forget to call step()
738
739Up is current data, Down is their subset with possibly delayed values
740*/
741class datalink_buffered: public datalink_part {
742protected:
743        //! History, ordered as \f$[Up_{t-1},Up_{t-2}, \ldots]\f$
744        vec history;
745        //! rv of the history
746        RV Hrv;
747        //! h2v : indeces in down
748        ivec h2v_down;
749        //! h2v : indeces in history
750        ivec h2v_hist;
751        //! v2h: indeces of up too be pushed to h
752        ivec v2h_up;
753public:
754
755        datalink_buffered() : datalink_part(), history ( 0 ), h2v_down ( 0 ), h2v_hist ( 0 ) {};
756        //! push current data to history
757        void store_data ( const vec &val_up ) {
758                if ( v2h_up.length() > 0 ) {
759                        history.shift_right ( 0, v2h_up.length() );
760                        history.set_subvector ( 0, val_up ( v2h_up ) );
761                }
762        }
763        //! Get val for myself from val of "Up"
764        vec pushdown ( const vec &val_up ) {
765                vec tmp ( downsize );
766                filldown ( val_up, tmp );
767                return tmp;
768        }
769
770        void filldown ( const vec &val_up, vec &val_down ) {
771                bdm_assert_debug ( val_down.length() >= downsize, "short val_down" );
772
773                set_subvector ( val_down, v2v_down, val_up ( v2v_up ) ); // copy direct values
774                set_subvector ( val_down, h2v_down, history ( h2v_hist ) ); // copy delayed values
775        }
776
777        void set_connection ( const RV &rv, const RV &rv_up );
778       
779        //! set history of variable given by \c rv1 to values of \c hist.
780        void set_history ( const RV& rv1, const vec &hist0 );
781};
782
783//! buffered datalink from 2 vectors to 1
784class datalink_2to1_buffered {
785protected:
786        //! link 1st vector to down
787        datalink_buffered dl1;
788        //! link 2nd vector to down
789        datalink_buffered dl2;
790public:
791        //! set connection between RVs
792        void set_connection ( const RV &rv, const RV &rv_up1, const RV &rv_up2 ) {
793                dl1.set_connection ( rv, rv_up1 );
794                dl2.set_connection ( rv, rv_up2 );
795        }
796        //! fill values of down from the values of the two up vectors
797        void filldown ( const vec &val1, const vec &val2, vec &val_down ) {
798                bdm_assert_debug ( val_down.length() >= dl1._downsize() + dl2._downsize(), "short val_down" );
799                dl1.filldown ( val1, val_down );
800                dl2.filldown ( val2, val_down );
801        }
802        //! update buffer
803        void step ( const vec &dt, const vec &ut ) {
804                dl1.store_data ( dt );
805                dl2.store_data ( ut );
806        }
807};
808
809
810
811//! Data link with a condition.
812class datalink_m2e: public datalink {
813protected:
814        //! Remember how long cond should be
815        int condsize;
816
817        //!upper_val-to-local_cond link, indices of the upper val
818        ivec v2c_up;
819
820        //!upper_val-to-local_cond link, indices of the local cond
821        ivec v2c_lo;
822
823public:
824        //! Constructor
825        datalink_m2e() : condsize ( 0 ) { }
826
827        //! Set connection between vectors
828        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up );
829
830        //!Construct condition
831        vec get_cond ( const vec &val_up );
832
833        //! Copy corresponding values to Up.condition
834        void pushup_cond ( vec &val_up, const vec &val, const vec &cond );
835};
836
837//!DataLink is a connection between pdf and its superordinate (Up)
838//! This class links
839class datalink_m2m: public datalink_m2e {
840protected:
841        //!cond-to-cond link, indices of the upper cond
842        ivec c2c_up;
843        //!cond-to-cond link, indices of the local cond
844        ivec c2c_lo;
845
846public:
847        //! Constructor
848        datalink_m2m() {};
849        //! Set connection between the vectors
850        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) {
851                datalink_m2e::set_connection ( rv, rvc, rv_up );
852                //establish c2c connection
853                rvc.dataind ( rvc_up, c2c_lo, c2c_up );
854//              bdm_assert_debug ( c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given" );
855        }
856
857        //! Get cond for myself from val and cond of "Up"
858        vec get_cond ( const vec &val_up, const vec &cond_up ) {
859                vec tmp ( condsize );
860                fill_cond ( val_up, cond_up, tmp );
861                return tmp;
862        }
863        //! fill condition
864        void fill_cond ( const vec &val_up, const vec &cond_up, vec& cond_out ) {
865                bdm_assert_debug ( cond_out.length() >= condsize, "dl.fill_cond: cond_out is too small" );
866                set_subvector ( cond_out, v2c_lo, val_up ( v2c_up ) );
867                set_subvector ( cond_out, c2c_lo, cond_up ( c2c_up ) );
868        }
869        //! Fill
870
871};
872
873
874//! \brief Combines RVs from a list of pdfs to a single one.
875RV get_composite_rv ( const Array<shared_ptr<pdf> > &pdfs, bool checkoverlap = false );
876
877/*! \brief Abstract class for discrete-time sources of data.
878
879The class abstracts operations of:
880\li  data aquisition,
881\li  data-preprocessing, such as  scaling of data,
882\li  data resampling from the task of estimation and control.
883Moreover, for controlled systems, it is able to receive the desired control action and perform it in the next step. (Or as soon as possible).
884
885The DataSource has three main data interaction structures:
886\li input, \f$ u_t \f$,
887\li output \f$ y_t \f$,
888\li data, \f$ d_t=[y_t,u_t, \ldots ]\f$ a collection of all inputs and outputs and possibly some internal variables too.
889
890*/
891
892class DS : public root {
893        LOG_LEVEL(DS,jednicka);
894protected:
895        //! size of data returned by \c getdata()
896        int dtsize;
897        //! size of data
898        int utsize;
899        //!size of output
900        int ytsize;
901        //!Description of data returned by \c getdata().
902        RV Drv;
903        //!Description of data witten by by \c write().
904        RV Urv; //
905        //!Description of output data
906        RV Yrv; //
907public:
908        //! default constructors
909        DS() : dtsize ( 0 ), utsize ( 0 ), ytsize ( 0 ), Drv(), Urv(), Yrv() {
910                log_level[jednicka] = true;
911        };
912
913        //! 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().
914        virtual int max_length() {
915                return std::numeric_limits< int >::max();
916        }
917        //! Returns full vector of observed data=[output, input]
918        virtual void getdata ( vec &dt ) const = 0;
919
920        //! Returns data records at indeces. Default is inefficent.
921        virtual void getdata ( vec &dt, const ivec &indeces ) {
922                vec tmp(dtsize);
923                getdata(tmp);
924                dt = tmp(indeces);
925        };
926
927        //! Accepts action variable and schedule it for application.   
928        virtual void write ( const vec &ut ) NOT_IMPLEMENTED_VOID;
929
930        //! Accepts action variables at specific indeces
931        virtual void write ( const vec &ut, const ivec &indeces ) NOT_IMPLEMENTED_VOID;
932
933        //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system.
934        virtual void step() = 0;
935
936        //! Register DS for logging into logger L
937        virtual void log_register ( logger &L,  const string &prefix );
938        //! Register DS for logging into logger L
939        virtual void log_write ( ) const;
940        //!access function
941        virtual const RV& _drv() const {
942                return Drv;
943        }
944        //!access function
945        const RV& _urv() const {
946                return Urv;
947        }
948        //!access function
949        const RV& _yrv() const {
950                return Yrv;
951        }
952        //! set random variables
953        virtual void set_drv ( const  RV &yrv, const RV &urv ) {
954                Yrv = yrv;
955                Drv = concat ( yrv, urv );
956                Urv = urv;
957        }
958};
959
960/*! \brief Bayesian Model of a system, i.e. all uncertainty is modeled by probabilities.
961
962This object represents exact or approximate evaluation of the Bayes rule:
963\f[
964f(\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})}
965\f]
966where:
967 * \f$ y_t \f$ is the variable
968Access to the resulting posterior density is via function \c posterior().
969
970As a "side-effect" it also evaluates log-likelihood of the data, which can be accessed via function _ll().
971It can also evaluate predictors of future values of \f$y_t\f$, see functions epredictor() and predictor().
972
973Alternatively, it can evaluate posterior density with rvc replaced by the given values, \f$ c_t \f$:
974\f[
975f(\theta_t | c_t, d_1,\ldots,d_t) \propto  f(y_t,\theta_t|c_t,\cdot, d_1,\ldots,d_{t-1})
976\f]
977
978*/
979
980class BM : public root {
981        LOG_LEVEL(BM,full,likelihood,bounds);
982
983protected:
984        //! Random variable of the data (optional)
985        RV yrv;
986        //! size of the data record
987        int dimy;
988        //! Name of extension variable
989        RV rvc;
990        //! size of the conditioning vector
991        int dimc;
992
993        //!Logarithm of marginalized data likelihood.
994        double ll;
995        //!  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.
996        bool evalll;
997
998public:
999        //! \name Constructors
1000        //! @{
1001
1002        BM() : yrv(), dimy ( 0 ), rvc(), dimc ( 0 ), ll ( 0 ), evalll ( true ) { };
1003        //      BM ( const BM &B ) :  yrv ( B.yrv ), dimy(B.dimy), rvc ( B.rvc ),dimc(B.dimc), ll ( B.ll ), evalll ( B.evalll ) {}
1004        //! \brief Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually!
1005        //! Prototype: \code BM* _copy() const {return new BM(*this);} \endcode
1006        virtual BM* _copy() const NOT_IMPLEMENTED(NULL);
1007        //!@}
1008
1009        //! \name Mathematical operations
1010        //!@{
1011
1012        /*! \brief Incremental Bayes rule
1013        @param dt vector of input data
1014        */
1015        virtual void bayes ( const vec &yt, const vec &cond = empty_vec ) = 0;
1016        //! Batch Bayes rule (columns of Dt are observations)
1017        virtual void bayes_batch ( const mat &Dt, const vec &cond = empty_vec );
1018        //! Batch Bayes rule (columns of Dt are observations, columns of Cond are conditions)
1019        virtual void bayes_batch ( const mat &Dt, const mat &Cond );
1020        //! Evaluates predictive log-likelihood of the given data record
1021        //! I.e. marginal likelihood of the data with the posterior integrated out.
1022        //! This function evaluates only \f$ y_t \f$, condition is assumed to be the last used in bayes().
1023        //! See bdm::BM::predictor for conditional version.
1024        virtual double logpred ( const vec &yt ) const = 0;
1025
1026        //! Matrix version of logpred
1027        vec logpred_mat ( const mat &Yt ) const {
1028                vec tmp ( Yt.cols() );
1029                for ( int i = 0; i < Yt.cols(); i++ ) {
1030                        tmp ( i ) = logpred ( Yt.get_col ( i ) );
1031                }
1032                return tmp;
1033        }
1034
1035        //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$
1036        virtual epdf* epredictor() const = 0;
1037
1038        //!Constructs conditional density of 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) \f$
1039        virtual pdf* predictor() const = 0;
1040
1041        //!@}
1042
1043
1044        //! \name Access to attributes
1045        //!@{
1046        //! access function
1047        const RV& _rvc() const {
1048                return rvc;
1049        }
1050        //! access function
1051        int dimensionc() const {
1052                return dimc;
1053        }
1054        //! access function
1055        int dimensiony() const {
1056                return dimy;
1057        }
1058        //! access function
1059        int dimension() const {
1060                return posterior().dimension();
1061        }
1062        //! access function
1063        const RV& _yrv() const {
1064                return yrv;
1065        }
1066        //! access function
1067        void set_yrv ( const RV &rv ) {
1068                yrv = rv;
1069        }
1070        //! access function
1071        void set_rvc ( const RV &rv ) {
1072                rvc = rv;
1073        }
1074        //! access to rv of the posterior
1075        void set_rv ( const RV &rv ) {
1076                const_cast<epdf&> ( posterior() ).set_rv ( rv );
1077        }
1078        //! access function
1079        void set_dim ( int dim ) {
1080                const_cast<epdf&> ( posterior() ).set_dim ( dim );
1081        }
1082        //! return internal log-likelihood of the last data vector
1083        double _ll() const {
1084                return ll;
1085        }
1086        //! switch evaluation of log-likelihood on/off
1087        void set_evalll ( bool evl0 ) {
1088                evalll = evl0;
1089        }
1090        //! return posterior density
1091        virtual const epdf& posterior() const = 0;
1092        //!@}
1093
1094        //! \name Logging of results
1095        //!@{
1096
1097        //! Add all logged variables to a logger
1098        //! Log levels two digits: xy where
1099        //!  * y = 0/1 log-likelihood is to be logged
1100        //!  * x = level of the posterior (typically 0/1/2 for nothing/mean/bounds)
1101        virtual void log_register ( logger &L, const string &prefix = "" );
1102
1103        //! Save results to the given logger, details of what is stored is configured by \c LIDs and \c options
1104        virtual void log_write ( ) const;
1105
1106        //!@}
1107        void from_setting ( const Setting &set ) {
1108                shared_ptr<RV> r = UI::build<RV> ( set, "yrv", UI::optional );
1109                if ( r ) {
1110                        set_yrv ( *r );
1111                }
1112                shared_ptr<RV> r2 = UI::build<RV> ( set, "rvc", UI::optional );
1113                if ( r2 ) {
1114                        rvc =   *r2;
1115                }
1116                shared_ptr<RV> r3 = UI::build<RV> ( set, "rv", UI::optional );
1117                if ( r3 ) {
1118                        set_rv ( *r3 );
1119                }
1120
1121                UI::get ( log_level, set, "log_level", UI::optional );
1122
1123        }
1124
1125        void to_setting ( Setting &set ) const {
1126                root::to_setting( set );
1127                UI::save( &yrv, set, "yrv" );
1128                UI::save( &rvc, set, "rvc" );           
1129                UI::save( &posterior()._rv(), set, "rv" );
1130                UI::save( log_level, set );
1131        }
1132
1133        void validate()
1134        {
1135                if ( log_level[full] ) {
1136                        const_cast<epdf&> ( posterior() ).log_level[epdf::deset] = true;
1137                } else {
1138                        if ( log_level[bounds] ) {
1139                                const_cast<epdf&> ( posterior() ).log_level[epdf::dva] = true;
1140                        } else {
1141                                const_cast<epdf&> ( posterior() ).log_level[epdf::jedna] = true;;
1142                        }
1143                        if ( log_level[likelihood] ) {
1144                                // TODO testovat tedy likelyhood misto 1.. log_level = 1;
1145                        }
1146                }
1147        }
1148};
1149
1150//! array of pointers to epdf
1151typedef Array<shared_ptr<epdf> > epdf_array;
1152//! array of pointers to pdf
1153typedef Array<shared_ptr<pdf> > pdf_array;
1154
1155template<class EPDF>
1156vec pdf_internal<EPDF>::samplecond ( const vec &cond ) {
1157        condition ( cond );
1158        vec temp = iepdf.sample();
1159        return temp;
1160}
1161
1162template<class EPDF>
1163mat pdf_internal<EPDF>::samplecond_mat ( const vec &cond, int N ) {
1164        condition ( cond );
1165        mat temp ( dimension(), N );
1166        vec smp ( dimension() );
1167        for ( int i = 0; i < N; i++ ) {
1168                smp = iepdf.sample();
1169                temp.set_col ( i, smp );
1170        }
1171
1172        return temp;
1173}
1174
1175template<class EPDF>
1176double pdf_internal<EPDF>::evallogcond ( const vec &yt, const vec &cond ) {
1177        double tmp;
1178        condition ( cond );
1179        tmp = iepdf.evallog ( yt );
1180        return tmp;
1181}
1182
1183template<class EPDF>
1184vec pdf_internal<EPDF>::evallogcond_mat ( const mat &Yt, const vec &cond ) {
1185        condition ( cond );
1186        return iepdf.evallog_mat ( Yt );
1187}
1188
1189template<class EPDF>
1190vec pdf_internal<EPDF>::evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) {
1191        condition ( cond );
1192        return iepdf.evallog_mat ( Yt );
1193}
1194
1195}; //namespace
1196#endif // BDMBASE_H
Note: See TracBrowser for help on using the browser.