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

Revision 1009, 45.5 kB (checked in by smidl, 14 years ago)

changes in bayes_batch

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