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

Revision 596, 27.7 kB (checked in by smidl, 15 years ago)

#37 almost finished

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