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

Revision 1063, 46.7 kB (checked in by mido, 14 years ago)

a small patch of documentation, to be contiuned..

  • 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
79RV name may be empty string! In that case, it is not a valid name but only a size holder. It will fail in comparison.
80*/
81
82class RV : public root {
83private:
84        typedef std::map<string, int> str2int_map;
85
86        //! Internal global variable storing sizes of RVs
87        static ivec SIZES;
88        //! Internal global variable storing names of RVs
89        static Array<string> NAMES;
90        //! TODO
91        const static int BUFFER_STEP;
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
144        RV ( string name, int sz, int tm = 0 );
145
146        //! Constructor of a single nameless RV
147        RV ( int sz, int tm = 0 );
148
149        // compiler-generated copy constructor is used
150        //!@}
151
152        //! \name Access functions
153        //!@{
154
155        //! State output, e.g. for debugging.
156        friend std::ostream &operator<< ( std::ostream &os, const RV &rv );
157
158        string to_string() const {
159                ostringstream o;
160                o << *this;
161                return o.str();
162        }
163
164        //! total size of a random variable
165        int _dsize() const {
166                return dsize;
167        }
168
169        //! access function
170        const ivec& _ids() const {
171                return ids;
172        }
173
174        //! Recount size of the corresponding data vector
175        int countsize() const;
176        //! Vector of cumulative sizes of RV
177        ivec cumsizes() const;
178        //! Number of named parts
179        int length() const {
180                return len;
181        }
182        int id ( int at ) const {
183                return ids ( at );
184        }
185        int size ( int at ) const {
186                return SIZES ( ids ( at ) );
187        }
188        int time ( int at ) const {
189                return times ( at );
190        }
191        std::string name ( int at ) const {
192                return NAMES ( ids ( at ) );
193        }
194        //! 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
195        std::string scalarname ( int scalat ) const;
196
197        void set_time ( int at, int time0 ) {
198                times ( at ) = time0;
199        }
200        //!@}
201
202        //! \name Algebra on Random Variables
203        //!@{
204
205        //! Find indices of self in another rv, \return ivec of the same size as self.
206        ivec findself ( const RV &rv2 ) const;
207        //! Find indices of self in another rv, ignore time, \return ivec of the same size as self.
208        ivec findself_ids ( const RV &rv2 ) const;
209        //! Compare if \c rv2 is identical to this \c RV
210        bool equal ( const RV &rv2 ) const;
211        //! Add (concat) another variable to the current one, \return true if all rv2 were added, false if rv2 is in conflict
212        bool add ( const RV &rv2 );
213        //! Subtract  another variable from the current one
214        RV subt ( const RV &rv2 ) const;
215        //! Select only variables at indices ind
216        RV subselect ( const ivec &ind ) const;
217
218        //! Select only variables at indices ind
219        RV operator() ( const ivec &ind ) const {
220                return subselect ( ind );
221        }
222
223        //! Select from data vector starting at di1 to di2
224        RV operator() ( int di1, int di2 ) const;
225
226        //! Shift \c time by delta.
227        void t_plus ( int delta );
228        //!@}
229
230        //! @{ \name Time manipulation functions
231        //! returns rvs with time set to 0 and removed duplicates
232        RV remove_time() const {
233                return RV ( unique ( ids ), dummy );
234        }
235        //! create new RV from the current one with time shifted by given value
236        RV copy_t ( int dt ) const {
237                RV tmp = *this;
238                tmp.t_plus ( dt );
239                return tmp;
240        }
241        //! return rvs with expanded delayes and sorted in the order of: \f$ [ rv_{0}, rv_{-1},\ldots  rv_{max_delay}]\f$
242        RV expand_delayes() const;
243        //!@}
244
245        //!\name Relation to vectors
246        //!@{
247
248        //! generate \c str from rv, by expanding sizes
249        str tostr() const;
250        //! when this rv is a part of bigger rv, this function returns indices of self in the data vector of the bigger crv.
251        //! Then, data can be copied via: data_of_this = cdata(ind);
252        ivec dataind ( const RV &crv ) const;
253        //! same as dataind but this time crv should not be complete supperset of rv.
254        ivec dataind_part ( const RV &crv ) const;
255        //! generate mutual indices when copying data between self and crv.
256        //! Data are copied via: data_of_this(selfi) = data_of_rv2(rv2i)
257        void dataind ( const RV &rv2, ivec &selfi, ivec &rv2i ) const;
258        //! Minimum time-offset
259        int mint() const {
260                return times.length() > 0 ? min ( times ) : 0;
261        }
262        //! Minimum time-offset of ids of given RVs
263        int mint ( const RV &rv ) const {
264                bvec belong = zeros_b ( len );
265                for ( int r = 0; r < rv.length(); r++ ) {
266                        belong = belong | ( ids == rv.id ( r ) );
267                }
268                return times.length() > 0 ? min ( get_from_bvec ( times, belong ) ) : 0;
269        }
270        //!@}
271
272        /*! \brief UI for class RV (description of data vectors)
273
274        \code
275        class = 'RV';
276        names = {'a', 'b', 'c', ...};   // UNIQUE IDENTIFIER same names = same variable
277                                                                        // names are also used when storing results
278        --- optional ---
279        sizes = [1, 2, 3, ...];         // size of each name. default = ones()
280                                                                        // if size = -1, it is found out from previous instances of the same name
281        times = [-1, -2, 0, ...];       // time shifts with respect to current time, default = zeros()
282        \endcode
283        */
284        void from_setting ( const Setting &set );
285
286        void to_setting ( Setting &set ) const;
287
288        //! Invalidate all named RVs. Use before initializing any RV instances, with care...
289        static void clear_all();
290        //! function for debugging RV related stuff
291        string show_all();
292
293};
294UIREGISTER ( RV );
295SHAREDPTR ( RV );
296
297//! Concat two random variables
298RV concat ( const RV &rv1, const RV &rv2 );
299
300
301
302//! This class stores a details that will be logged to a logger
303//!
304//! This is only the first part of the whole declaration, which has to be however separated into
305//! two different classes for allowing the compilation of source code. For more details
306//! see logger::add_setting(...) method and mainly log_level_template<T>::template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const
307//! method. For the reason the second one is templated, it was necessary to declare this whole class.
308template<class T> class log_level_intermediate : public log_level_base {
309protected:
310        //! boolean flags related indicating which details will be logged to a logger
311        bitset<32> values;
312
313        //! default constructor is protected to prevent creating instances elsewhere than in log_level_template descendant class
314        log_level_intermediate( ) {
315                int len = names().length();
316                ids.set_size( len );
317                for( int i = 0; i<len; i++ )
318                {
319                        ids(i).set_size ( 1 );
320                        ids(i) = -1;
321                }       
322        }
323public:
324        //! a general utility transforming a comma-separated sequence of strings into an instance of Array<strings>
325        static Array<string> string2Array( const string &input )
326        {
327                string result = input;
328                string::size_type loc;
329                while( loc = result.find( ',' ), loc != string::npos )
330                        result[loc] = ' ';
331                return Array<string>("{ " + result + " }" );
332        } 
333
334        //! this method adds new id to its proper position and return the name of this position
335        string store_id_and_give_name( enum T::log_level_enums const log_level_enum,  int enum_subindex, int id ) {
336                if( ids(log_level_enum).length() <= enum_subindex )
337                        ids(log_level_enum).set_size( enum_subindex+1, true );
338                ids(log_level_enum)(enum_subindex) = id; 
339
340                // here we remove a "log" prefix from name, i.e., for instance it transforms "logevidence" to "evidence"
341                ostringstream stream;
342                string name_with_prefix = names()(log_level_enum);
343                string possible_log_prefix = name_with_prefix.substr(0,3);
344                if( possible_log_prefix == "log" )
345                        stream << name_with_prefix.substr(3,name_with_prefix.length()-3);
346                else 
347                        stream << name_with_prefix;
348
349                // add number to name only in the case there are more registered vectors with the same log_level_enum
350                if( ids(log_level_enum).length() > 1 )
351                        stream << "_" << enum_subindex;
352               
353                return stream.str();
354        }
355
356        //! string equivalents of the used enumerations which are filled with a help of #LOG_LEVEL macro within class T
357        const Array<string> &names() const
358        {
359                return T::log_level_names();
360        }
361
362        //! read only operator for testing individual fields of log_level
363        //!
364        //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe
365        bool operator [] (const enum T::log_level_enums &log_level_enum ) const
366        {
367                return values[log_level_enum];
368        }
369
370        //! operator for setting an individual field of log_level
371        //!
372        //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe
373        bitset<32>::reference operator [] (const enum T::log_level_enums &log_level_enum )
374        {
375                return values[log_level_enum];
376        }
377};
378//UIREGISTER IS FORBIDDEN FOR THIS CLASS,  AS IT SHOULD BE LOADED ONLY THROUGH THE SPECIALIZED UI::GET(...) METHOD
379
380
381/*!
382@brief Class for storing results (and semi-results) of an experiment
383
384This 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.
385*/
386class logger : public root {
387protected:
388        //! RVs of all logged variables.
389        Array<RV> entries;
390        //! Names of logged quantities, e.g. names of algorithm variants
391        Array<string> names;
392        //! Root Setting for storing Settings
393        Config setting_conf;
394        //! list of Settings for specific ids
395        Array<Setting*> settings;
396
397        //! log this instance to Setting
398        //!
399        //! this method has to be called only through \c log_level class to assure the validity of the passed id
400        template<class U> void log_setting ( int id, const U data ) {
401                UI::save(data, *settings ( id ) );
402        }
403
404        //! log this vector
405        //!
406        //! this method has to be called only through \c log_level class to assure the validity of the passed id
407        virtual void log_vector ( int id, const vec &v ) NOT_IMPLEMENTED_VOID;
408
409        //! log this double
410        //!
411        //! this method has to be called only through \c log_level class to assure the validity of the passed id
412        virtual void log_double ( int id, const double &d ) NOT_IMPLEMENTED_VOID;
413
414        //! it is necessary to allow log_levels to call log_setting, log_vector and log_double methods
415        template<class T> friend class log_level_template;
416public:
417        //!separator of prefixes of entries
418        //!
419        //! It is a constant string, thus it can be safely declared as public without creating any accessor method
420        const string separator;
421
422        //!Default constructor
423        logger ( const string separator ) : entries ( 0 ), names ( 0 ), separator ( separator ) {}
424
425        //!Destructor calls the finalize method
426        ~logger() {
427                finalize(); 
428        }
429
430        //! sets up the ids identifier in the passed log_level instance to permit future calls of the log_level_template<T>::store(...) method
431        //!
432        //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure
433        //! Entries with empty RV will be ignored
434        //!
435        //! passing the last parameter \c enum_subindex one can store multiple vectors in the position of one enum
436        template<class T> void add_vector ( log_level_intermediate<T> &log_level, enum T::log_level_enums const log_level_enum, const RV &rv, const string &prefix, int enum_subindex = 0 )
437        {
438                if( !log_level.registered_logger )
439                        log_level.registered_logger = this;
440                else
441                        bdm_assert_debug ( log_level.registered_logger == this, "This log_level is already registered to another logger!");
442
443                if ( rv._dsize() == 0 ) 
444                        return;
445               
446                int id = entries.length();
447                string adjusted_name = log_level.store_id_and_give_name( log_level_enum, enum_subindex, id );
448
449                names = concat ( names, prefix + separator + adjusted_name ); // diff
450                entries.set_length ( id + 1, true );
451                entries ( id ) = rv;
452        }
453
454        //! sets up the ids identifier in the passed log_level instance to permit future calls of the log_level_template<T>::store(...) method
455        //!
456        //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure
457        //!
458        //! To allow both arguments log_level and log_level_enum be templated, it was necessary to declare log_level_intermediate<T> class.
459        //! This way we check compatibility of the passed log_level and log_level_enum, which would be impossible using just log_level_base class
460        //! here.
461        //!
462        //!
463        //! passing the last parameter \c enum_subindex one can store multiple settings in the position of one enum
464        template<class T> void add_setting ( log_level_intermediate<T> &log_level, enum T::log_level_enums const log_level_enum,  const string &prefix, int enum_subindex = 0 ) {
465                if( !log_level.registered_logger )
466                        log_level.registered_logger = this;
467                else
468                        bdm_assert_debug ( log_level.registered_logger == this, "This log_level is already registered to another logger!");
469
470                Setting &root = setting_conf.getRoot(); 
471                int id = root.getLength(); //root must be group!!                       
472                string adjusted_name = log_level.store_id_and_give_name( log_level_enum, enum_subindex, id );
473                settings.set_length ( id + 1, true );                   
474                settings ( id ) = &root.add ( prefix + separator + adjusted_name, Setting::TypeList );         
475        }
476
477        //! Shifts storage position for another time step.
478        virtual void step() = 0;
479
480        //! Finalize storing information
481        //!
482        //! This method is called either directly or via destructor ~logger(), therefore it has to permit repetitive calls for the case it is called twice
483        virtual void finalize() {};
484
485        //! Initialize the storage
486        virtual void init() {};
487};
488
489//! This class stores a details that will be logged to a logger
490template<class T> class log_level_template : public log_level_intermediate<T> {
491public:
492
493        //! Set log_levels according to the Setting element
494        void from_setting ( const Setting &element )
495        {
496                string raw_log_level;
497                UI::get( raw_log_level, element );
498                Array<string> loaded_log_level = this->string2Array( raw_log_level );
499       
500                this->values.reset();
501
502                for( int i = 0; i < loaded_log_level.length(); i++ )
503                        for( int j = 0; j < this->names().length(); j++ ){
504                                if( loaded_log_level(i) == this->names()(j)  ) 
505                                {
506                                        this->values[j] = true;
507                                        break;
508                                } 
509                        }
510        }
511
512        //! Store log_levels into the Setting element
513        void to_setting ( Setting &element ) const 
514        {
515                // HERE WE WANT NOT TO DELETE PREVIOUS DATA STORED BY OTHER LOG_LEVELS, SEE SPECIAL IMPLEMENTATION OF UI::GET(...) FOR THIS CLASS
516                const char* ch_elem=( const char* ) element;
517                string string_to_write;
518                if (ch_elem)
519                        string_to_write=ch_elem;
520                else
521                        string_to_write="";
522
523                for( unsigned int i = 0; i < this->values.size(); i++ )
524                        if( this->values[i] ) 
525                        {
526                                if( string_to_write.length() > 0 )
527                                        string_to_write = string_to_write + ',';
528                                string_to_write = string_to_write + this->names()(i);
529                        }
530                       
531                element = string_to_write;
532        }
533
534        //! This method stores a vector to the proper place in registered logger
535        //!
536        //! parameter \c enum_subindex identifies the precise position of vector in the case there is more vectors registered to with this enum
537        void store( const enum T::log_level_enums log_level_enum, const vec &vect, int enum_subindex = 0 ) const
538        {
539                bdm_assert_debug( this->registered_logger != NULL, "You have to register instance to a logger first! Use root::log_register(...) method.");
540                bdm_assert_debug( ids( log_level_enum )( enum_subindex ) >= 0, "This particular vector was not added to logger! Use logger::add_vector(...) method.");
541                this->registered_logger->log_vector( ids( log_level_enum )( enum_subindex ), vect );
542        }
543
544        //! This method stores a double to the proper place in registered logger
545        //!
546        //! parameter \c enum_subindex identifies the precise position of double in the case there is more doubles registered to with this enum
547        void store( const enum T::log_level_enums log_level_enum, const double &dbl, int enum_subindex = 0 ) const
548        {
549                bdm_assert_debug( this->registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method.");
550                bdm_assert_debug( ids( log_level_enum )( enum_subindex ) >= 0, "This particular double was not added to logger! Use logger::add_vector(...) method.");
551                this->registered_logger->log_double( ids( log_level_enum )( enum_subindex ), dbl );
552        }
553
554        //! This method stores a Setting obtained by call of UI::save( data, .. ) to the proper place in registered logger
555        //!
556        //! parameter \c enum_subindex identifies the precise position of setting in the case there is more settings registered to with this enum
557        template<class U> void store( const enum T::log_level_enums log_level_enum, const U data, int enum_subindex = 0 ) const
558        {                       
559                bdm_assert_debug( this->registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method.");
560                bdm_assert_debug( ids( log_level_enum )(enum_subindex ) >= 0, "This particular vector was not added to logger! Use logger::add_setting(...) method.");
561                this->registered_logger->log_setting( ids( log_level_enum )( enum_subindex ), data);
562        }
563};
564//UIREGISTER IS FORBIDDEN FOR THIS CLASS,  AS IT SHOULD BE LOADED ONLY THROUGH THE SPECIALIZED UI::GET(...) METHOD
565
566
567/*!
568  \def LOG_LEVEL(classname,...)
569  \brief Macro for defining a log_level attribute with a specific set of enumerations related to a specific class
570
571  This macro has to be called within a class declaration. Its argument \a classname has to correspond to that wrapping class.
572  This macro defines a log_level instance which can be modified either directly or by the means of #bdm::UI class.
573
574  One of the main purposes of this macro is to allow variability in using enumerations. By relating them to their names through
575  an array of strings, we are no more dependant on their precise ordering. What is more, we can add or remove any without harming
576  any applications which are using this library.
577
578  \todo Write a more detailed explanation including also examples
579
580  \ref ui
581*/
582#define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_intermediate<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_template<classname>::string2Array( #__VA_ARGS__ ); return log_level_names; }
583
584
585//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv
586class fnc : public root {       
587protected:
588        //! Length of the output vector
589        int dimy;
590        //! Length of the input vector
591        int dimc;
592public:
593        //!default constructor
594        fnc() {};
595        //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond
596        virtual vec eval ( const vec &cond ) {
597                return vec ( 0 );
598        };
599
600        //! access function
601        int dimension() const {
602                return dimy;
603        }
604        //! access function
605        int dimensionc() const {
606                return dimc;
607        }
608        void from_setting(const Setting &set){
609                UI::get(dimy, set, "dim", UI::optional);
610                UI::get(dimc, set, "dimc", UI::optional);
611        }
612};
613
614class epdf;
615
616//! 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.
617class pdf : public root {
618protected:
619        //!dimension of the condition
620        int dimc;
621
622        //! random variable in condition
623        RV rvc;
624
625        //! dimension of random variable
626        int dim;
627
628        //! random variable
629        RV rv;
630
631public:
632        //! \name Constructors
633        //! @{
634
635        pdf() : dimc ( 0 ), rvc(), dim ( 0 ), rv() { }
636
637        pdf ( const pdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), dim ( m.dim ), rv ( m.rv ) { }
638
639        //!@}
640
641        //! \name Matematical operations
642        //!@{
643
644        //! 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
645        virtual vec samplecond ( const vec &cond ) = 0;
646
647        //! 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
648        virtual mat samplecond_mat ( const vec &cond, int N );
649
650        //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently.
651        virtual double evallogcond ( const vec &yt, const vec &cond ) = 0;
652
653        //! Matrix version of evallogcond
654        virtual vec evallogcond_mat ( const mat &Yt, const vec &cond ) {
655                vec v ( Yt.cols() );
656                for ( int i = 0; i < Yt.cols(); i++ ) {
657                        v ( i ) = evallogcond ( Yt.get_col ( i ), cond );
658                }
659                return v;
660        }
661
662        //! Array<vec> version of evallogcond
663        virtual vec evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) {
664                vec v ( Yt.length() );
665                for ( int i = 0; i < Yt.length(); i++ ) {
666                        v ( i ) = evallogcond ( Yt( i ), cond );
667                }
668                return v;
669        }
670
671        //! \name Access to attributes
672        //! @{
673
674        const RV& _rv() const {
675                return rv;
676        }
677        const RV& _rvc() const {
678                return rvc;
679        }
680
681        int dimension() const {
682                return dim;
683        }
684        int dimensionc() {
685                return dimc;
686        }
687
688        //! access function
689        void set_dim ( int d ) {
690                dim = d;
691        }
692        //! access function
693        void set_dimc ( int d ) {
694                dimc = d;
695        }
696        //! Load from structure with elements:
697        //!  \code
698        //! { class = "pdf_offspring",
699        //!   rv = {class="RV", names=(...),}; // RV describing meaning of random variable
700        //!   rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition
701        //!   // elements of offsprings
702        //! }
703        //! \endcode
704        //!@}
705        void from_setting ( const Setting &set );
706
707        void to_setting ( Setting &set ) const;
708        //!@}
709
710        //! \name Connection to other objects
711        //!@{
712        void set_rvc ( const RV &rvc0 ) {
713                rvc = rvc0;
714        }
715        void set_rv ( const RV &rv0 ) {
716                rv = rv0;
717        }
718
719        //! Names of variables stored in RV are considered to be valid only if their size match size of the parameters (dim).
720        bool isnamed() const {
721                return ( dim == rv._dsize() ) && ( dimc == rvc._dsize() );
722        }
723        //!@}
724};
725SHAREDPTR ( pdf );
726
727//! Probability density function with numerical statistics, e.g. posterior density.
728class epdf : public pdf {
729        //! \var log_level_enums logmean
730        //! log mean value of the density when requested
731       
732        //! \var log_level_enums loglbound
733        //! log lower bound of the density (see function qbounds)
734       
735        //! \var log_level_enums logubound
736        //! log upper bound of the density (see function qbounds)
737       
738        LOG_LEVEL(epdf,logmean,loglbound,logubound);
739
740public:
741        /*! \name Constructors
742         Construction of each epdf should support two types of constructors:
743        \li empty constructor,
744        \li copy constructor,
745
746        The following constructors should be supported for convenience:
747        \li constructor followed by calling \c set_parameters() WHICH IS OBSOLETE (TODO)
748        \li constructor accepting random variables calling \c set_rv()
749
750         All internal data structures are constructed as empty. Their values (including sizes) will be
751         set by method \c set_parameters() WHICH IS OBSOLETE (TODO). This way references can be initialized in constructors.
752        @{*/
753        epdf() {};
754        epdf ( const epdf &e ) : pdf ( e ) {};
755       
756       
757        //!@}
758
759        //! \name Matematical Operations
760        //!@{
761
762        //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$
763        virtual vec sample() const = 0;
764
765        //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$  from density \f$ f_x(rv)\f$
766        virtual mat sample_mat ( int N ) const;
767
768        //! Compute log-probability of argument \c val
769        //! In case the argument is out of suport return -Infinity
770        virtual double evallog ( const vec &val ) const = 0;
771       
772        //! Compute log-probability of multiple values argument \c val
773        virtual vec evallog_mat ( const mat &Val ) const;
774
775        //! Compute log-probability of multiple values argument \c val
776        virtual vec evallog_mat ( const Array<vec> &Avec ) const;
777
778        //! Return conditional density on the given RV, the remaining rvs will be in conditioning
779        virtual shared_ptr<pdf> condition ( const RV &rv ) const;
780
781        //! Return marginal density on the given RV, the remainig rvs are intergrated out
782        virtual shared_ptr<epdf> marginal ( const RV &rv ) const;
783
784        virtual vec mean() const = 0;
785
786        //! return expected variance (not covariance!)
787        virtual vec variance() const = 0;
788
789        //! return expected covariance -- default is diag(variance)!!
790        virtual mat covariance() const {return diag(variance());};
791       
792        //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default
793        virtual void qbounds ( vec &lb, vec &ub, double percentage = 0.95 ) const {
794                vec mea = mean();
795                vec std = sqrt ( variance() );
796                lb = mea - 2 * std;
797                ub = mea + 2 * std;
798        };
799        //! Set statistics to match given input epdf. Typically it copies statistics from epdf of the same type and projects those form different types
800        //! \param pdf0 epdf to match
801        void set_statistics(const epdf *pdf0) NOT_IMPLEMENTED_VOID;
802        //!@}
803
804        //! \name Connection to other classes
805        //! Description of the random quantity via attribute \c rv is optional.
806        //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization
807        //! and \c conditioning \c rv has to be set. NB:
808        //! @{
809
810        //! store values of the epdf on the following levels:
811        //!  #1 mean
812        //!  #2 mean + lower & upper bound
813        void log_register ( logger &L, const string &prefix );
814
815        void log_write() const;
816        //!@}
817
818        //! \name Access to attributes
819        //! @{
820
821        //! Load from structure with elements:
822        //!  \code
823        //! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable
824        //!   // elements of offsprings
825        //! }
826        //! \endcode
827        //!@}
828        void from_setting ( const Setting &set );
829        void to_setting ( Setting &set ) const;
830
831        vec samplecond ( const vec &cond ) {
832                return sample();
833        }
834        double evallogcond ( const vec &val, const vec &cond ) {
835                return evallog ( val );
836        }
837};
838SHAREDPTR ( epdf );
839
840//! pdf with internal epdf that is modified by function \c condition
841template <class EPDF>
842class pdf_internal: public pdf {
843protected :
844        //! Internal epdf used for sampling
845        EPDF iepdf;
846public:
847        //! constructor
848        pdf_internal() : pdf(), iepdf() {
849        }
850
851        //! Update \c iepdf so that it represents this pdf conditioned on \c rvc = cond
852        //! This function provides convenient reimplementation in offsprings
853        virtual void condition ( const vec &cond ) = 0;
854
855        //!access function to iepdf
856        EPDF& e() {
857                return iepdf;
858        }
859
860        //! Reimplements samplecond using \c condition()
861        vec samplecond ( const vec &cond );
862        //! Reimplements evallogcond using \c condition()
863        double evallogcond ( const vec &val, const vec &cond );
864        //! Efficient version of evallogcond for matrices
865        virtual vec evallogcond_mat ( const mat &Dt, const vec &cond );
866        //! Efficient version of evallogcond for Array<vec>
867        virtual vec evallogcond_mat ( const Array<vec> &Dt, const vec &cond );
868        //! Efficient version of samplecond
869        virtual mat samplecond_mat ( const vec &cond, int N );
870
871        void validate() {
872                pdf::validate();
873                iepdf.validate();
874                if ( rv._dsize() < iepdf._rv()._dsize() ) {
875                        rv = iepdf._rv();
876                };
877                dim = iepdf.dimension();
878        }
879};
880
881/*! \brief DataLink is a connection between two data vectors Up and Down
882
883Up can be longer than Down. Down must be fully present in Up (TODO optional)
884See chart:
885\dot
886digraph datalink {
887  node [shape=record];
888  subgraph cluster0 {
889    label = "Up";
890      up [label="<1>|<2>|<3>|<4>|<5>"];
891    color = "white"
892}
893  subgraph cluster1{
894    label = "Down";
895    labelloc = b;
896      down [label="<1>|<2>|<3>"];
897    color = "white"
898}
899    up:1 -> down:1;
900    up:3 -> down:2;
901    up:5 -> down:3;
902}
903\enddot
904
905*/
906class datalink {
907protected:
908        //! Remember how long val should be
909        int downsize;
910
911        //! Remember how long val of "Up" should be
912        int upsize;
913
914        //! val-to-val link, indices of the upper val
915        ivec v2v_up;
916
917public:
918        //! Constructor
919        datalink() : downsize ( 0 ), upsize ( 0 ) { }
920
921        //! Convenience constructor
922        datalink ( const RV &rv, const RV &rv_up ) {
923                set_connection ( rv, rv_up );
924        }
925
926        //! set connection, rv must be fully present in rv_up
927        virtual void set_connection ( const RV &rv, const RV &rv_up );
928
929        //! set connection using indices
930        virtual void set_connection ( int ds, int us, const ivec &upind );
931
932        //! Get val for myself from val of "Up"
933        vec pushdown ( const vec &val_up ) {
934                vec tmp ( downsize );
935                filldown ( val_up, tmp );
936                return tmp;
937        }
938        //! Get val for vector val_down from val of "Up"
939        virtual void filldown ( const vec &val_up, vec &val_down ) {
940                bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" );
941                val_down = val_up ( v2v_up );
942        }
943        //! Fill val of "Up" by my pieces
944        virtual void pushup ( vec &val_up, const vec &val ) {
945                bdm_assert_debug ( downsize == val.length(), "Wrong val" );
946                bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" );
947                set_subvector ( val_up, v2v_up, val );
948        }
949        //! access functions
950        int _upsize() {
951                return upsize;
952        }
953        //! access functions
954        int _downsize() {
955                return downsize;
956        }
957        //! for future use
958        virtual ~datalink() {}
959};
960
961/*! Extension of datalink to fill only part of Down
962*/
963class datalink_part : public datalink {
964protected:
965        //! indices of values in vector downsize
966        ivec v2v_down;
967public:
968        void set_connection ( const RV &rv, const RV &rv_up );
969        //! Get val for vector val_down from val of "Up"
970        void filldown ( const vec &val_up, vec &val_down ) {
971                set_subvector ( val_down, v2v_down, val_up ( v2v_up ) );
972        }
973};
974
975/*! \brief Datalink that buffers delayed values - do not forget to call step()
976
977Up is current data, Down is their subset with possibly delayed values
978*/
979class datalink_buffered: public datalink_part {
980protected:
981        //! History, ordered as \f$[Up_{t-1},Up_{t-2}, \ldots]\f$
982        vec history;
983        //! rv of the history
984        RV Hrv;
985        //! h2v : indices in down
986        ivec h2v_down;
987        //! h2v : indices in history
988        ivec h2v_hist;
989        //! v2h: indices of up too be pushed to h
990        ivec v2h_up;
991public:
992
993        datalink_buffered() : datalink_part(), history ( 0 ), h2v_down ( 0 ), h2v_hist ( 0 ) {};
994        //! push current data to history
995        void store_data ( const vec &val_up ) {
996                if ( v2h_up.length() > 0 ) {
997                        history.shift_right ( 0, v2h_up.length() );
998                        history.set_subvector ( 0, val_up ( v2h_up ) );
999                }
1000        }
1001        //! Get val for myself from val of "Up"
1002        vec pushdown ( const vec &val_up ) {
1003                vec tmp ( downsize );
1004                filldown ( val_up, tmp );
1005                return tmp;
1006        }
1007
1008        void filldown ( const vec &val_up, vec &val_down ) {
1009                bdm_assert_debug ( val_down.length() >= downsize, "short val_down" );
1010
1011                set_subvector ( val_down, v2v_down, val_up ( v2v_up ) ); // copy direct values
1012                set_subvector ( val_down, h2v_down, history ( h2v_hist ) ); // copy delayed values
1013        }
1014
1015        void set_connection ( const RV &rv, const RV &rv_up );
1016       
1017        //! set history of variable given by \c rv1 to values of \c hist.
1018        void set_history ( const RV& rv1, const vec &hist0 );
1019};
1020
1021class vec_from_vec: public vec {
1022        protected:
1023                datalink_part dl;
1024                int vecfromlen;
1025        public:
1026                void update(const vec &v1){
1027                        bdm_assert_debug(length()==dl._downsize(),"vec_from_vec incompatible");
1028                        bdm_assert_debug(v1.length()==vecfromlen,"This vec was connected to vec of length "+num2str(vecfromlen)+
1029                        ", but vec of length "+num2str(v1.length())+" was obtained"  );
1030                        dl.filldown(v1,*this);
1031                };
1032                void connect(const RV &vecrv, const RV & vec1){
1033                        bdm_assert(vecrv._dsize()==length(),"Description of this vector, "+ vecrv.to_string() +" does not math it length: " + num2str(length()));
1034                        dl.set_connection(vecrv,vec1);
1035                        bdm_assert(dl._downsize()==length(), "Rv of this vector, "+vecrv.to_string() +" was not found in given rv: "+vec1.to_string());
1036                };
1037};
1038
1039class vec_from_2vec: public vec {
1040        protected:
1041                datalink_part dl1;
1042                datalink_part dl2;
1043        public:
1044                void update(const vec &v1, const vec &v2){
1045                        bdm_assert_debug(length()==dl1._downsize()+dl2._downsize(),"vec_from_vec incompatible");
1046                        bdm_assert_debug(v1.length()>=dl1._upsize(),"vec_from_vec incompatible");
1047                        bdm_assert_debug(v2.length()>=dl2._upsize(),"vec_from_vec incompatible");
1048                        dl1.filldown(v1,*this);
1049                        dl2.filldown(v2,*this);
1050                };
1051                void connect(const RV &rv, const RV & rv1, const RV &rv2){
1052                        dl1.set_connection(rv,rv1);
1053                        dl2.set_connection(rv,rv2);
1054                        set_length(rv._dsize());
1055                };
1056};
1057
1058//! buffered datalink from 2 vectors to 1
1059class datalink_2to1_buffered {
1060protected:
1061        //! link 1st vector to down
1062        datalink_buffered dl1;
1063        //! link 2nd vector to down
1064        datalink_buffered dl2;
1065public:
1066        //! set connection between RVs
1067        void set_connection ( const RV &rv, const RV &rv_up1, const RV &rv_up2 ) {
1068                dl1.set_connection ( rv, rv_up1 );
1069                dl2.set_connection ( rv, rv_up2 );
1070        }
1071        //! fill values of down from the values of the two up vectors
1072        void filldown ( const vec &val1, const vec &val2, vec &val_down ) {
1073                bdm_assert_debug ( val_down.length() >= dl1._downsize() + dl2._downsize(), "short val_down" );
1074                dl1.filldown ( val1, val_down );
1075                dl2.filldown ( val2, val_down );
1076        }
1077        //! update buffer
1078        void step ( const vec &dt, const vec &ut ) {
1079                dl1.store_data ( dt );
1080                dl2.store_data ( ut );
1081        }
1082};
1083
1084
1085
1086//! Data link with a condition.
1087class datalink_m2e: public datalink {
1088protected:
1089        //! Remember how long cond should be
1090        int condsize;
1091
1092        //!upper_val-to-local_cond link, indices of the upper val
1093        ivec v2c_up;
1094
1095        //!upper_val-to-local_cond link, indices of the local cond
1096        ivec v2c_lo;
1097
1098public:
1099        //! Constructor
1100        datalink_m2e() : condsize ( 0 ) { }
1101
1102        //! Set connection between vectors
1103        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up );
1104
1105        //!Construct condition
1106        vec get_cond ( const vec &val_up );
1107
1108        //! Copy corresponding values to Up.condition
1109        void pushup_cond ( vec &val_up, const vec &val, const vec &cond );
1110};
1111
1112//!DataLink is a connection between pdf and its superordinate (Up)
1113//! This class links
1114class datalink_m2m: public datalink_m2e {
1115protected:
1116        //!cond-to-cond link, indices of the upper cond
1117        ivec c2c_up;
1118        //!cond-to-cond link, indices of the local cond
1119        ivec c2c_lo;
1120
1121public:
1122        //! Constructor
1123        datalink_m2m() {};
1124        //! Set connection between the vectors
1125        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) {
1126                datalink_m2e::set_connection ( rv, rvc, rv_up );
1127                //establish c2c connection
1128                rvc.dataind ( rvc_up, c2c_lo, c2c_up );
1129//              bdm_assert_debug ( c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given" );
1130        }
1131
1132        //! Get cond for myself from val and cond of "Up"
1133        vec get_cond ( const vec &val_up, const vec &cond_up ) {
1134                vec tmp ( condsize );
1135                fill_cond ( val_up, cond_up, tmp );
1136                return tmp;
1137        }
1138        //! fill condition
1139        void fill_cond ( const vec &val_up, const vec &cond_up, vec& cond_out ) {
1140                bdm_assert_debug ( cond_out.length() >= condsize, "dl.fill_cond: cond_out is too small" );
1141                set_subvector ( cond_out, v2c_lo, val_up ( v2c_up ) );
1142                set_subvector ( cond_out, c2c_lo, cond_up ( c2c_up ) );
1143        }
1144        //! Fill
1145
1146};
1147
1148
1149//! \brief Combines RVs from a list of pdfs to a single one.
1150RV get_composite_rv ( const Array<shared_ptr<pdf> > &pdfs, bool checkoverlap = false );
1151
1152/*! \brief Abstract class for discrete-time sources of data.
1153
1154The class abstracts operations of:
1155\li  data aquisition,
1156\li  data-preprocessing, such as  scaling of data,
1157\li  data resampling from the task of estimation and control.
1158Moreover, for controlled systems, it is able to receive the desired control action and perform it in the next step. (Or as soon as possible).
1159
1160The DataSource has three main data interaction structures:
1161\li input, \f$ u_t \f$, which are described via RVs in attribute \c urv
1162\li observations \f$ d_t \f$, which are described in \c drv
1163In simulators, dt may contain "hidden" variables as well.
1164
1165*/
1166
1167class DS : public root {
1168        //! \var log_level_enums logdt
1169        //! log all outputs
1170
1171        //! \var log_level_enums logut
1172        //! log all inputs
1173        LOG_LEVEL(DS,logdt,logut);
1174
1175protected:
1176        //! size of data returned by \c getdata()
1177        int dtsize;
1178        //! size of data
1179        int utsize;
1180        //!Description of data returned by \c getdata().
1181        RV Drv;
1182        //!Description of data witten by by \c write().
1183        RV Urv; //
1184public:
1185        //! publicly acessible vector of observations
1186        vec dt;
1187        //! publicly writeble vector of inputs
1188        vec ut;
1189       
1190        //! default constructors
1191        DS() : dtsize ( 0 ), utsize ( 0 ), Drv(), Urv(){
1192                log_level[logdt] = true;
1193                log_level[logut] = true;
1194        };
1195
1196        //! 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().
1197        virtual int max_length() {
1198                return std::numeric_limits< int >::max();
1199        }
1200        //! Returns full vector of observed data=[output, input]
1201        virtual void getdata ( vec &dt_out ) const {
1202                bdm_assert_debug(dtsize==dt.length(),"DS::getdata: dt is not of declared size;"); 
1203                dt_out=dt;
1204        };
1205
1206        //! Returns data records at indices. Default is inefficent.
1207        virtual void getdata ( vec &dt_out, const ivec &indices ) {
1208                bdm_assert_debug(max(indices)<dt.length(), "DS::getdata: indeces out of bounds");
1209                dt_out = dt(indices);
1210        };
1211
1212        //! Accepts action variable and schedule it for application.   
1213        virtual void write ( const vec &ut ) NOT_IMPLEMENTED_VOID;
1214
1215        //! Accepts action variables at specific indices
1216        virtual void write ( const vec &ut, const ivec &indices ) NOT_IMPLEMENTED_VOID;
1217
1218        //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system.
1219        virtual void step() = 0;
1220
1221        //! Register DS for logging into logger L
1222        virtual void log_register ( logger &L,  const string &prefix );
1223        //! Register DS for logging into logger L
1224        virtual void log_write ( ) const;
1225        //!access function
1226        virtual const RV& _drv() const {
1227                return Drv;
1228        }
1229        //!access function
1230        const RV& _urv() const {
1231                return Urv;
1232        }
1233
1234        /*! Create object from the following structure
1235        \code
1236        drv  = RV({"names",...},[..sizes..]);            % decription of observed data using bdm::RV::from_setting
1237        urv  = RV({"names",...},[..sizes..]);            % decription of input data using bdm::RV::from_setting
1238        log_level = 'logdt,logut';               % when set, both the simulated data and the inputs are stored to the logger
1239                                                 % By default both are on. It makes sense to switch them off e.g. for MemDS where the data are already stored.
1240        \endcode
1241        */
1242        void from_setting ( const Setting &set );
1243
1244        void validate();
1245};
1246
1247/*! \brief Bayesian Model of a system, i.e. all uncertainty is modeled by probabilities.
1248
1249This object represents exact or approximate evaluation of the Bayes rule:
1250\f[
1251f(\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})}
1252\f]
1253where:
1254 * \f$ y_t \f$ is the variable
1255Access to the resulting posterior density is via function \c posterior().
1256
1257As a "side-effect" it also evaluates log-likelihood of the data, which can be accessed via function _ll().
1258It can also evaluate predictors of future values of \f$y_t\f$, see functions epredictor() and predictor().
1259
1260Alternatively, it can evaluate posterior density with rvc replaced by the given values, \f$ c_t \f$:
1261\f[
1262f(\theta_t | c_t, d_1,\ldots,d_t) \propto  f(y_t,\theta_t|c_t,\cdot, d_1,\ldots,d_{t-1})
1263\f]
1264
1265*/
1266
1267class BM : public root {
1268        //! \var log_level_enums logfull
1269        //! log full description of posterior in descriptive structure
1270
1271        //! \var log_level_enums logevidence
1272        //! log value of eveidence in each step
1273       
1274        //! \var log_level_enums logbounds
1275        //! log lower and upper bounds of estimates
1276        LOG_LEVEL(BM,logfull,logevidence,logbounds);
1277
1278protected:
1279        //! Random variable of the data (optional)
1280        RV yrv;
1281        //! size of the data record
1282        int dimy;
1283        //! Name of extension variable
1284        RV rvc;
1285        //! size of the conditioning vector
1286        int dimc;
1287
1288        //!Logarithm of marginalized data likelihood.
1289        double ll;
1290        //!  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.
1291        bool evalll;
1292
1293public:
1294        //! \name Constructors
1295        //! @{
1296
1297        BM() : yrv(), dimy ( 0 ), rvc(), dimc ( 0 ), ll ( 0 ), evalll ( true ) { };
1298        //      BM ( const BM &B ) :  yrv ( B.yrv ), dimy(B.dimy), rvc ( B.rvc ),dimc(B.dimc), ll ( B.ll ), evalll ( B.evalll ) {}
1299        //! \brief Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually!
1300        //! Prototype: \code BM* _copy() const {return new BM(*this);} \endcode
1301        virtual BM* _copy() const NOT_IMPLEMENTED(NULL);
1302        //!@}
1303
1304        //! \name Mathematical operations
1305        //!@{
1306
1307        /*! \brief Incremental Bayes rule
1308        @param yt vector of input data
1309        */
1310        virtual void bayes ( const vec &yt, const vec &cond = empty_vec ) =0;
1311        //! Batch Bayes rule (columns of Dt are observations)
1312        virtual double bayes_batch ( const mat &Dt, const vec &cond = empty_vec );
1313        //! Batch Bayes rule (columns of Dt are observations, columns of Cond are conditions)
1314        virtual double bayes_batch ( const mat &Dt, const mat &Cond );
1315        //! Evaluates predictive log-likelihood of the given data record
1316        //! I.e. marginal likelihood of the data with the posterior integrated out.
1317        //! This function evaluates only \f$ y_t \f$, condition is assumed to be the last used in bayes().
1318        //! See bdm::BM::predictor for conditional version.
1319        virtual double logpred ( const vec &yt, const vec &cond ) const NOT_IMPLEMENTED(0.0);
1320
1321        //! Matrix version of logpred
1322        vec logpred_mat ( const mat &Yt, const mat &Cond ) const {
1323                vec tmp ( Yt.cols() );
1324                for ( int i = 0; i < Yt.cols(); i++ ) {
1325                        tmp ( i ) = logpred ( Yt.get_col ( i ), Cond.get_col(i) );
1326                }
1327                return tmp;
1328        }
1329
1330        //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$
1331        virtual epdf* epredictor(const vec &cond=vec()) const NOT_IMPLEMENTED(NULL);
1332
1333        //!Constructs conditional density of 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) \f$
1334        virtual pdf* predictor() const NOT_IMPLEMENTED(NULL);
1335
1336        //!@}
1337
1338
1339        //! \name Access to attributes
1340        //!@{
1341        //! access function
1342        const RV& _rvc() const {
1343                return rvc;
1344        }
1345        //! access function
1346        int dimensionc() const {
1347                return dimc;
1348        }
1349        //! access function
1350        int dimensiony() const {
1351                return dimy;
1352        }
1353        //! access function
1354        int dimension() const {
1355                return posterior().dimension();
1356        }
1357        //! access function
1358        const RV& _rv() const {
1359                return posterior()._rv();
1360        }
1361        //! access function
1362        const RV& _yrv() const {
1363                return yrv;
1364        }
1365        //! access function
1366        void set_yrv ( const RV &rv ) {
1367                yrv = rv;
1368        }
1369        //! access function
1370        void set_rvc ( const RV &rv ) {
1371                rvc = rv;
1372        }
1373        //! access to rv of the posterior
1374        void set_rv ( const RV &rv ) {
1375                const_cast<epdf&> ( posterior() ).set_rv ( rv );
1376        }
1377        //! access function
1378        void set_dim ( int dim ) {
1379                const_cast<epdf&> ( posterior() ).set_dim ( dim );
1380        }
1381        //! return internal log-likelihood of the last data vector
1382        double _ll() const {
1383                return ll;
1384        }
1385        //! switch evaluation of log-likelihood on/off
1386        void set_evalll ( bool evl0 ) {
1387                evalll = evl0;
1388        }
1389        //! return posterior density
1390        virtual const epdf& posterior() const = 0;
1391       
1392        epdf& prior() {return const_cast<epdf&>(posterior());}
1393        //! set prior density -- same as posterior but writable
1394        virtual void set_prior(const epdf *pdf0) NOT_IMPLEMENTED_VOID;
1395       
1396        //!@}
1397
1398        //! \name Logging of results
1399        //!@{
1400
1401        //! Add all logged variables to a logger
1402        //! Log levels two digits: xy where
1403        //!  * y = 0/1 log-likelihood is to be logged
1404        //!  * x = level of the posterior (typically 0/1/2 for nothing/mean/bounds)
1405        virtual void log_register ( logger &L, const string &prefix = "" );
1406
1407        //! Save results to the given logger, details of what is stored is configured by \c LIDs and \c options
1408        virtual void log_write ( ) const;
1409
1410        //!@}
1411        //! \brief Read names of random variables from setting
1412        /*!
1413        reading structure:
1414        \TODO check if not remove... rv...
1415        \code
1416        yrv  = RV();               // names of modelled data
1417        rvc  = RV();               // names of data in condition
1418    rv   = RV();               // names of parameters
1419        log_level = "logmean";     // identifiers of levels of detail to store to loggers
1420        \endcode
1421        */
1422        void from_setting ( const Setting &set ) {
1423                UI::get(yrv, set, "yrv", UI::optional );
1424                UI::get(rvc, set, "rvc", UI::optional );
1425                RV r;
1426                UI::get(r, set, "rv", UI::optional );
1427                set_rv ( r );
1428       
1429                UI::get ( log_level, set, "log_level", UI::optional );
1430        }
1431
1432        void to_setting ( Setting &set ) const {
1433                root::to_setting( set );
1434                UI::save( &yrv, set, "yrv" );
1435                UI::save( &rvc, set, "rvc" );           
1436                UI::save( &posterior()._rv(), set, "rv" );
1437                UI::save( log_level, set );
1438        }
1439
1440        //! process
1441        void validate()
1442        {
1443                if ( log_level[logbounds] ) {
1444                        const_cast<epdf&> ( posterior() ).log_level[epdf::loglbound] = true;
1445                } else {
1446                        const_cast<epdf&> ( posterior() ).log_level[epdf::logmean] = true;;
1447                }
1448        }
1449};
1450
1451//! array of pointers to epdf
1452typedef Array<shared_ptr<epdf> > epdf_array;
1453//! array of pointers to pdf
1454typedef Array<shared_ptr<pdf> > pdf_array;
1455
1456template<class EPDF>
1457vec pdf_internal<EPDF>::samplecond ( const vec &cond ) {
1458        condition ( cond );
1459        vec temp = iepdf.sample();
1460        return temp;
1461}
1462
1463template<class EPDF>
1464mat pdf_internal<EPDF>::samplecond_mat ( const vec &cond, int N ) {
1465        condition ( cond );
1466        mat temp ( dimension(), N );
1467        vec smp ( dimension() );
1468        for ( int i = 0; i < N; i++ ) {
1469                smp = iepdf.sample();
1470                temp.set_col ( i, smp );
1471        }
1472
1473        return temp;
1474}
1475
1476template<class EPDF>
1477double pdf_internal<EPDF>::evallogcond ( const vec &yt, const vec &cond ) {
1478        double tmp;
1479        condition ( cond );
1480        tmp = iepdf.evallog ( yt );
1481        return tmp;
1482}
1483
1484template<class EPDF>
1485vec pdf_internal<EPDF>::evallogcond_mat ( const mat &Yt, const vec &cond ) {
1486        condition ( cond );
1487        return iepdf.evallog_mat ( Yt );
1488}
1489
1490template<class EPDF>
1491vec pdf_internal<EPDF>::evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) {
1492        condition ( cond );
1493        return iepdf.evallog_mat ( Yt );
1494}
1495
1496}; //namespace
1497#endif // BDMBASE_H
Note: See TracBrowser for help on using the browser.