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

Revision 513, 27.3 kB (checked in by smidl, 15 years ago)

quickies:
no assert in mpdf::_rvc
mmix accepts empty Coms

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