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

Revision 927, 43.6 kB (checked in by smidl, 14 years ago)

traffic agents -- pro BDM > r904

  • 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//! This class stores a details that will be logged to a logger
300//!
301//! This is only the first part of the whole declaration, which has to be however separated into
302//! two different classes for allowing the compilation of source code. For more details
303//! 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
304//! method. For the reason the second one is templated, it was necessary to declare this whole class.
305template<class T> class log_level_intermediate : public log_level_base {
306public:
307        //! this method adds new id to its proper position and return the name of this position
308        string store_id_and_give_name( enum T::log_level_enums const log_level_enum,  int enum_subindex, int id ) {
309//              int ids_len = ids(log_level_enum).length(); <== compiler suggest to remove
310                if( ids(log_level_enum).length() <= enum_subindex )
311                        ids(log_level_enum).set_size( enum_subindex+1, true );
312                ids(log_level_enum)(enum_subindex) = id; 
313
314                // here we remove a "log" prefix from name, i.e., for instance it transforms "logevidence" to "evidence"
315                ostringstream stream;
316                string name_with_prefix = names()(log_level_enum);
317                string possible_log_prefix = name_with_prefix.substr(0,3);
318                if( possible_log_prefix == "log" )
319                        stream << name_with_prefix.substr(3,name_with_prefix.length()-3);
320                else 
321                        stream << name_with_prefix;
322
323                // add number to name only in the case there are more registered vectors with the same log_level_enum
324                if( ids(log_level_enum).length() > 1 )
325                        stream << "*" << enum_subindex;
326               
327                return stream.str();
328        }
329
330        log_level_intermediate( ) {
331                int len = names().length();
332                ids.set_size( len );
333                for( int i = 0; i<len; i++ )
334                {
335                        ids(i).set_size ( 1 );
336                        ids(i) = -1;
337                }
338        }
339
340        //! string equivalents of the used enumerations which are filled with a help of #LOG_LEVEL macro within class T
341        const Array<string> &names() const
342        {
343                return T::log_level_names();
344        }
345
346        //! read only operator for testing individual fields of log_level
347        //!
348        //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe
349        bool operator [] (const enum T::log_level_enums &log_level_enum ) const
350        {
351                return values[log_level_enum];
352        }
353
354        //! operator for setting an individual field of log_level
355        //!
356        //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe
357        bitset<32>::reference operator [] (const enum T::log_level_enums &log_level_enum )
358        {
359                return values[log_level_enum];
360        }
361};
362
363
364/*!
365@brief Class for storing results (and semi-results) of an experiment
366
367This 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.
368*/
369class logger : public root {
370protected:
371        //! RVs of all logged variables.
372        Array<RV> entries;
373        //! Names of logged quantities, e.g. names of algorithm variants
374        Array<string> names;
375        //! Root Setting for storing Settings
376        Config setting_conf;
377        //! list of Settings for specific ids
378        Array<Setting*> settings;
379
380        //! log this instance to Setting
381        //!
382        //! this method has to be called only through \c log_level class to assure the validity of the passed id
383        template<class U> void log_setting ( int id, const U data ) {
384                UI::save(data, *settings ( id ) );
385        }
386
387        //! log this vector
388        //!
389        //! this method has to be called only through \c log_level class to assure the validity of the passed id
390        virtual void log_vector ( int id, const vec &v ) NOT_IMPLEMENTED_VOID;
391
392        //! log this double
393        //!
394        //! this method has to be called only through \c log_level class to assure the validity of the passed id
395        virtual void log_double ( int id, const double &d ) NOT_IMPLEMENTED_VOID;
396
397        //! it is necessary to allow log_levels to call log_setting, log_vector and log_double methods
398        template<class T> friend class log_level_template;
399public:
400        //!separator of prefixes of entries
401        //!
402        //! It is a constant string, thus it can be safely declared as public without creating any accessor method
403        const string separator;
404
405        //!Default constructor
406        logger ( const string separator ) : entries ( 0 ), names ( 0 ), separator ( separator ) {}
407
408        //!Destructor calls the finalize method
409        ~logger() {
410                finalize(); 
411        }
412
413        //! sets up the ids identifier in the passed log_level instance to permit future calls of the log_level_template<T>::store(...) method
414        //!
415        //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure
416        //! Entries with empty RV will be ignored
417        //!
418        //! passing the last parameter \c enum_subindex one can store multiple vectors in the position of one enum
419        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 )
420        {
421                if( !log_level.registered_logger )
422                        log_level.registered_logger = this;
423                else
424                        bdm_assert_debug ( log_level.registered_logger == this, "This log_level is already registered to another logger!");
425
426                if ( rv._dsize() == 0 ) 
427                        return;
428               
429                int id = entries.length();
430                string adjusted_name = log_level.store_id_and_give_name( log_level_enum, enum_subindex, id );
431
432                names = concat ( names, prefix + separator + adjusted_name ); // diff
433                entries.set_length ( id + 1, true );
434                entries ( id ) = rv;
435        }
436
437        //! sets up the ids identifier in the passed log_level instance to permit future calls of the log_level_template<T>::store(...) method
438        //!
439        //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure
440        //!
441        //! To allow both arguments log_level and log_level_enum be templated, it was necessary to declare log_level_intermediate<T> class.
442        //! This way we check compatibility of the passed log_level and log_level_enum, which would be impossible using just log_level_base class
443        //! here.
444        //!
445        //!
446        //! passing the last parameter \c enum_subindex one can store multiple settings in the position of one enum
447        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 ) {
448                if( !log_level.registered_logger )
449                        log_level.registered_logger = this;
450                else
451                        bdm_assert_debug ( log_level.registered_logger == this, "This log_level is already registered to another logger!");
452
453                Setting &root = setting_conf.getRoot(); 
454                int id = root.getLength(); //root must be group!!                       
455                string adjusted_name = log_level.store_id_and_give_name( log_level_enum, enum_subindex, id );
456                settings.set_length ( id + 1, true );                   
457                settings ( id ) = &root.add ( prefix + separator + adjusted_name, Setting::TypeList );         
458        }
459
460        //! Shifts storage position for another time step.
461        virtual void step() = 0;
462
463        //! Finalize storing information
464        //!
465        //! This method is called either directly or via destructor ~logger(), therefore it has to permit repetitive calls for the case it is called twice
466        virtual void finalize() {};
467
468        //! Initialize the storage
469        virtual void init() {};
470};
471
472//! This class stores a details that will be logged to a logger
473template<class T> class log_level_template : public log_level_intermediate<T> {
474public:
475        //! This method stores a vector to the proper place in registered logger
476        //!
477        //! parameter \c enum_subindex identifies the precise position of vector in the case there is more vectors registered to with this enum
478        void store( const enum T::log_level_enums log_level_enum, const vec &vect, int enum_subindex = 0 ) const
479        {
480                bdm_assert_debug( this->registered_logger != NULL, "You have to register instance to a logger first! Use root::log_register(...) method.");
481                bdm_assert_debug( ids( log_level_enum )( enum_subindex ) >= 0, "This particular vector was not added to logger! Use logger::add_vector(...) method.");
482                this->registered_logger->log_vector( ids( log_level_enum )( enum_subindex ), vect );
483        }
484
485        //! This method stores a double to the proper place in registered logger
486        //!
487        //! parameter \c enum_subindex identifies the precise position of double in the case there is more doubles registered to with this enum
488        void store( const enum T::log_level_enums log_level_enum, const double &dbl, int enum_subindex = 0 ) const
489        {
490                bdm_assert_debug( this->registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method.");
491                bdm_assert_debug( ids( log_level_enum )( enum_subindex ) >= 0, "This particular double was not added to logger! Use logger::add_vector(...) method.");
492                this->registered_logger->log_double( ids( log_level_enum )( enum_subindex ), dbl );
493        }
494
495        //! This method stores a Setting obtained by call of UI::save( data, .. ) to the proper place in registered logger
496        //!
497        //! parameter \c enum_subindex identifies the precise position of setting in the case there is more settings registered to with this enum
498        //!
499        //! If this method was not templated, we could store whole body of this class in cpp file without explicitly touching registered_logger->log_setting(...) here.
500        //! (it would not be straightforward, though, still there are some enums which had to be converted into integers but it could be done without loosing type control)
501        //! This way, it would not be necessary to declare log_level_intermediate<T> class and we could declare log_level_template<T>
502        //! before the logger class itself with a mere foroward declaration of logger. In our case, however, touching of registered_logger->log_setting
503        //! implies that friend declaration is not enough and we are lost in a circle. And just by cutting this circle we obtains log_level_intermediate<T> class.
504        //! Howg.)
505        template<class U> void store( const enum T::log_level_enums log_level_enum, const U data, int enum_subindex = 0 ) const
506        {                       
507                bdm_assert_debug( this->registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method.");
508                bdm_assert_debug( ids( log_level_enum )(enum_subindex ) >= 0, "This particular vector was not added to logger! Use logger::add_setting(...) method.");
509                this->registered_logger->log_setting( ids( log_level_enum )( enum_subindex ), data);
510        }
511};
512
513/*!
514  \def LOG_LEVEL(classname,...)
515  \brief Macro for defining a log_level attribute with a specific set of enumerations related to a specific class
516
517  This macro has to be called within a class declaration. Its argument \a classname has to correspond to that wrapping class.
518  This macro defines a log_level instance which can be modified either directly or by the means of #UI class.
519
520  One of the main purposes of this macro is to allow variability in using enumerations. By relating them to their names through
521  an array of strings, we are no more dependant on their precise ordering. What is more, we can add or remove any without harming
522  any applications which are using this library.
523
524  \todo Write a more detailed explanation including also examples
525
526  \ref ui
527*/
528#define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_template<classname>; friend class log_level_intermediate<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_base::string2Array( #__VA_ARGS__ ); return log_level_names; }
529
530
531//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv
532class fnc : public root {       
533protected:
534        //! Length of the output vector
535        int dimy;
536        //! Length of the input vector
537        int dimc;
538public:
539        //!default constructor
540        fnc() {};
541        //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond
542        virtual vec eval ( const vec &cond ) {
543                return vec ( 0 );
544        };
545
546        //! access function
547        int dimension() const {
548                return dimy;
549        }
550        //! access function
551        int dimensionc() const {
552                return dimc;
553        }
554        void from_setting(const Setting &set){
555                UI::get(dimy, set, "dim", UI::optional);
556                UI::get(dimc, set, "dimc", UI::optional);
557        }
558};
559
560class epdf;
561
562//! 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.
563class pdf : public root {
564protected:
565        //!dimension of the condition
566        int dimc;
567
568        //! random variable in condition
569        RV rvc;
570
571        //! dimension of random variable
572        int dim;
573
574        //! random variable
575        RV rv;
576
577public:
578        //! \name Constructors
579        //! @{
580
581        pdf() : dimc ( 0 ), rvc(), dim ( 0 ), rv() { }
582
583        pdf ( const pdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), dim ( m.dim ), rv ( m.rv ) { }
584
585        //!@}
586
587        //! \name Matematical operations
588        //!@{
589
590        //! 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
591        virtual vec samplecond ( const vec &cond ) = 0;
592
593        //! 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
594        virtual mat samplecond_mat ( const vec &cond, int N );
595
596        //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently.
597        virtual double evallogcond ( const vec &yt, const vec &cond ) = 0;
598
599        //! Matrix version of evallogcond
600        virtual vec evallogcond_mat ( const mat &Yt, const vec &cond ) {
601                vec v ( Yt.cols() );
602                for ( int i = 0; i < Yt.cols(); i++ ) {
603                        v ( i ) = evallogcond ( Yt.get_col ( i ), cond );
604                }
605                return v;
606        }
607
608        //! Array<vec> version of evallogcond
609        virtual vec evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) {
610                vec v ( Yt.length() );
611                for ( int i = 0; i < Yt.length(); i++ ) {
612                        v ( i ) = evallogcond ( Yt( i ), cond );
613                }
614                return v;
615        }
616
617        //! \name Access to attributes
618        //! @{
619
620        const RV& _rv() const {
621                return rv;
622        }
623        const RV& _rvc() const {
624                return rvc;
625        }
626
627        int dimension() const {
628                return dim;
629        }
630        int dimensionc() {
631                return dimc;
632        }
633
634        //! access function
635        void set_dim ( int d ) {
636                dim = d;
637        }
638        //! access function
639        void set_dimc ( int d ) {
640                dimc = d;
641        }
642        //! Load from structure with elements:
643        //!  \code
644        //! { class = "pdf_offspring",
645        //!   rv = {class="RV", names=(...),}; // RV describing meaning of random variable
646        //!   rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition
647        //!   // elements of offsprings
648        //! }
649        //! \endcode
650        //!@}
651        void from_setting ( const Setting &set );
652
653        void to_setting ( Setting &set ) const;
654        //!@}
655
656        //! \name Connection to other objects
657        //!@{
658        void set_rvc ( const RV &rvc0 ) {
659                rvc = rvc0;
660        }
661        void set_rv ( const RV &rv0 ) {
662                rv = rv0;
663        }
664
665        //! Names of variables stored in RV are considered to be valid only if their size match size of the parameters (dim).
666        bool isnamed() const {
667                return ( dim == rv._dsize() ) && ( dimc == rvc._dsize() );
668        }
669        //!@}
670};
671SHAREDPTR ( pdf );
672
673//! Probability density function with numerical statistics, e.g. posterior density.
674class epdf : public pdf {
675        //! \var log_level_enums logmean
676        //! log mean value of the density when requested
677       
678        //! \var log_level_enums loglbound
679        //! log lower bound of the density (see function qbounds)
680       
681        //! \var log_level_enums logubound
682        //! log upper bound of the density (see function qbounds)
683       
684        //! \var log_level_enums logfull
685        //! log full record of the density in the form of setting
686        LOG_LEVEL(epdf,logmean,loglbound,logubound,logfull);
687
688public:
689        /*! \name Constructors
690         Construction of each epdf should support two types of constructors:
691        \li empty constructor,
692        \li copy constructor,
693
694        The following constructors should be supported for convenience:
695        \li constructor followed by calling \c set_parameters() WHICH IS OBSOLETE (TODO)
696        \li constructor accepting random variables calling \c set_rv()
697
698         All internal data structures are constructed as empty. Their values (including sizes) will be
699         set by method \c set_parameters() WHICH IS OBSOLETE (TODO). This way references can be initialized in constructors.
700        @{*/
701        epdf() {};
702        epdf ( const epdf &e ) : pdf ( e ) {};
703       
704       
705        //!@}
706
707        //! \name Matematical Operations
708        //!@{
709
710        //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$
711        virtual vec sample() const = 0;
712
713        //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$  from density \f$ f_x(rv)\f$
714        virtual mat sample_mat ( int N ) const;
715
716        //! Compute log-probability of argument \c val
717        //! In case the argument is out of suport return -Infinity
718        virtual double evallog ( const vec &val ) const = 0;
719       
720        //! Compute log-probability of multiple values argument \c val
721        virtual vec evallog_mat ( const mat &Val ) const;
722
723        //! Compute log-probability of multiple values argument \c val
724        virtual vec evallog_mat ( const Array<vec> &Avec ) const;
725
726        //! Return conditional density on the given RV, the remaining rvs will be in conditioning
727        virtual shared_ptr<pdf> condition ( const RV &rv ) const;
728
729        //! Return marginal density on the given RV, the remainig rvs are intergrated out
730        virtual shared_ptr<epdf> marginal ( const RV &rv ) const;
731
732        virtual vec mean() const = 0;
733
734        //! return expected variance (not covariance!)
735        virtual vec variance() const = 0;
736
737        //! return expected covariance -- default is diag(variance)!!
738        virtual mat covariance() const {return diag(variance());};
739       
740        //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default
741        virtual void qbounds ( vec &lb, vec &ub, double percentage = 0.95 ) const {
742                vec mea = mean();
743                vec std = sqrt ( variance() );
744                lb = mea - 2 * std;
745                ub = mea + 2 * std;
746        };
747        //! Set statistics to match given input epdf. Typically it copies statistics from epdf of the same type and projects those form different types
748        //! \param pdf0 epdf to match
749        //! \param option placeholder for potential options
750        void set_statistics(const epdf *pdf0) NOT_IMPLEMENTED_VOID;
751        //!@}
752
753        //! \name Connection to other classes
754        //! Description of the random quantity via attribute \c rv is optional.
755        //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization
756        //! and \c conditioning \c rv has to be set. NB:
757        //! @{
758
759        //! store values of the epdf on the following levels:
760        //!  #1 mean
761        //!  #2 mean + lower & upper bound
762        void log_register ( logger &L, const string &prefix );
763
764        void log_write() const;
765        //!@}
766
767        //! \name Access to attributes
768        //! @{
769
770        //! Load from structure with elements:
771        //!  \code
772        //! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable
773        //!   // elements of offsprings
774        //! }
775        //! \endcode
776        //!@}
777        void from_setting ( const Setting &set ) {
778                root::from_setting( set );
779                shared_ptr<RV> r = UI::build<RV> ( set, "rv", UI::optional );
780                if ( r ) {
781                        set_rv ( *r );
782                }
783        }
784
785        void to_setting ( Setting &set ) const {
786                // we do not want to store rvc, therfore, pdf::to_setting( set ) is omitted
787                root::to_setting(set);
788
789                UI::save( &rv, set, "rv" );
790        }
791
792        vec samplecond ( const vec &cond ) {
793                return sample();
794        }
795        double evallogcond ( const vec &val, const vec &cond ) {
796                return evallog ( val );
797        }
798};
799SHAREDPTR ( epdf );
800
801//! pdf with internal epdf that is modified by function \c condition
802template <class EPDF>
803class pdf_internal: public pdf {
804protected :
805        //! Internal epdf used for sampling
806        EPDF iepdf;
807public:
808        //! constructor
809        pdf_internal() : pdf(), iepdf() {
810        }
811
812        //! Update \c iepdf so that it represents this pdf conditioned on \c rvc = cond
813        //! This function provides convenient reimplementation in offsprings
814        virtual void condition ( const vec &cond ) = 0;
815
816        //!access function to iepdf
817        EPDF& e() {
818                return iepdf;
819        }
820
821        //! Reimplements samplecond using \c condition()
822        vec samplecond ( const vec &cond );
823        //! Reimplements evallogcond using \c condition()
824        double evallogcond ( const vec &val, const vec &cond );
825        //! Efficient version of evallogcond for matrices
826        virtual vec evallogcond_mat ( const mat &Dt, const vec &cond );
827        //! Efficient version of evallogcond for Array<vec>
828        virtual vec evallogcond_mat ( const Array<vec> &Dt, const vec &cond );
829        //! Efficient version of samplecond
830        virtual mat samplecond_mat ( const vec &cond, int N );
831
832        void validate() {
833                iepdf.validate();
834                if ( rv._dsize() < iepdf._rv()._dsize() ) {
835                        rv = iepdf._rv();
836                };
837                dim = iepdf.dimension();
838        }
839};
840
841/*! \brief DataLink is a connection between two data vectors Up and Down
842
843Up can be longer than Down. Down must be fully present in Up (TODO optional)
844See chart:
845\dot
846digraph datalink {
847  node [shape=record];
848  subgraph cluster0 {
849    label = "Up";
850      up [label="<1>|<2>|<3>|<4>|<5>"];
851    color = "white"
852}
853  subgraph cluster1{
854    label = "Down";
855    labelloc = b;
856      down [label="<1>|<2>|<3>"];
857    color = "white"
858}
859    up:1 -> down:1;
860    up:3 -> down:2;
861    up:5 -> down:3;
862}
863\enddot
864
865*/
866class datalink {
867protected:
868        //! Remember how long val should be
869        int downsize;
870
871        //! Remember how long val of "Up" should be
872        int upsize;
873
874        //! val-to-val link, indices of the upper val
875        ivec v2v_up;
876
877public:
878        //! Constructor
879        datalink() : downsize ( 0 ), upsize ( 0 ) { }
880
881        //! Convenience constructor
882        datalink ( const RV &rv, const RV &rv_up ) {
883                set_connection ( rv, rv_up );
884        }
885
886        //! set connection, rv must be fully present in rv_up
887        virtual void set_connection ( const RV &rv, const RV &rv_up );
888
889        //! set connection using indices
890        virtual void set_connection ( int ds, int us, const ivec &upind );
891
892        //! Get val for myself from val of "Up"
893        vec pushdown ( const vec &val_up ) {
894                vec tmp ( downsize );
895                filldown ( val_up, tmp );
896                return tmp;
897        }
898        //! Get val for vector val_down from val of "Up"
899        virtual void filldown ( const vec &val_up, vec &val_down ) {
900                bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" );
901                val_down = val_up ( v2v_up );
902        }
903        //! Fill val of "Up" by my pieces
904        virtual void pushup ( vec &val_up, const vec &val ) {
905                bdm_assert_debug ( downsize == val.length(), "Wrong val" );
906                bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" );
907                set_subvector ( val_up, v2v_up, val );
908        }
909        //! access functions
910        int _upsize() {
911                return upsize;
912        }
913        //! access functions
914        int _downsize() {
915                return downsize;
916        }
917        //! for future use
918        virtual ~datalink() {}
919};
920
921/*! Extension of datalink to fill only part of Down
922*/
923class datalink_part : public datalink {
924protected:
925        //! indices of values in vector downsize
926        ivec v2v_down;
927public:
928        void set_connection ( const RV &rv, const RV &rv_up );
929        //! Get val for vector val_down from val of "Up"
930        void filldown ( const vec &val_up, vec &val_down ) {
931                set_subvector ( val_down, v2v_down, val_up ( v2v_up ) );
932        }
933};
934
935/*! \brief Datalink that buffers delayed values - do not forget to call step()
936
937Up is current data, Down is their subset with possibly delayed values
938*/
939class datalink_buffered: public datalink_part {
940protected:
941        //! History, ordered as \f$[Up_{t-1},Up_{t-2}, \ldots]\f$
942        vec history;
943        //! rv of the history
944        RV Hrv;
945        //! h2v : indices in down
946        ivec h2v_down;
947        //! h2v : indices in history
948        ivec h2v_hist;
949        //! v2h: indices of up too be pushed to h
950        ivec v2h_up;
951public:
952
953        datalink_buffered() : datalink_part(), history ( 0 ), h2v_down ( 0 ), h2v_hist ( 0 ) {};
954        //! push current data to history
955        void store_data ( const vec &val_up ) {
956                if ( v2h_up.length() > 0 ) {
957                        history.shift_right ( 0, v2h_up.length() );
958                        history.set_subvector ( 0, val_up ( v2h_up ) );
959                }
960        }
961        //! Get val for myself from val of "Up"
962        vec pushdown ( const vec &val_up ) {
963                vec tmp ( downsize );
964                filldown ( val_up, tmp );
965                return tmp;
966        }
967
968        void filldown ( const vec &val_up, vec &val_down ) {
969                bdm_assert_debug ( val_down.length() >= downsize, "short val_down" );
970
971                set_subvector ( val_down, v2v_down, val_up ( v2v_up ) ); // copy direct values
972                set_subvector ( val_down, h2v_down, history ( h2v_hist ) ); // copy delayed values
973        }
974
975        void set_connection ( const RV &rv, const RV &rv_up );
976       
977        //! set history of variable given by \c rv1 to values of \c hist.
978        void set_history ( const RV& rv1, const vec &hist0 );
979};
980
981//! buffered datalink from 2 vectors to 1
982class datalink_2to1_buffered {
983protected:
984        //! link 1st vector to down
985        datalink_buffered dl1;
986        //! link 2nd vector to down
987        datalink_buffered dl2;
988public:
989        //! set connection between RVs
990        void set_connection ( const RV &rv, const RV &rv_up1, const RV &rv_up2 ) {
991                dl1.set_connection ( rv, rv_up1 );
992                dl2.set_connection ( rv, rv_up2 );
993        }
994        //! fill values of down from the values of the two up vectors
995        void filldown ( const vec &val1, const vec &val2, vec &val_down ) {
996                bdm_assert_debug ( val_down.length() >= dl1._downsize() + dl2._downsize(), "short val_down" );
997                dl1.filldown ( val1, val_down );
998                dl2.filldown ( val2, val_down );
999        }
1000        //! update buffer
1001        void step ( const vec &dt, const vec &ut ) {
1002                dl1.store_data ( dt );
1003                dl2.store_data ( ut );
1004        }
1005};
1006
1007
1008
1009//! Data link with a condition.
1010class datalink_m2e: public datalink {
1011protected:
1012        //! Remember how long cond should be
1013        int condsize;
1014
1015        //!upper_val-to-local_cond link, indices of the upper val
1016        ivec v2c_up;
1017
1018        //!upper_val-to-local_cond link, indices of the local cond
1019        ivec v2c_lo;
1020
1021public:
1022        //! Constructor
1023        datalink_m2e() : condsize ( 0 ) { }
1024
1025        //! Set connection between vectors
1026        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up );
1027
1028        //!Construct condition
1029        vec get_cond ( const vec &val_up );
1030
1031        //! Copy corresponding values to Up.condition
1032        void pushup_cond ( vec &val_up, const vec &val, const vec &cond );
1033};
1034
1035//!DataLink is a connection between pdf and its superordinate (Up)
1036//! This class links
1037class datalink_m2m: public datalink_m2e {
1038protected:
1039        //!cond-to-cond link, indices of the upper cond
1040        ivec c2c_up;
1041        //!cond-to-cond link, indices of the local cond
1042        ivec c2c_lo;
1043
1044public:
1045        //! Constructor
1046        datalink_m2m() {};
1047        //! Set connection between the vectors
1048        void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) {
1049                datalink_m2e::set_connection ( rv, rvc, rv_up );
1050                //establish c2c connection
1051                rvc.dataind ( rvc_up, c2c_lo, c2c_up );
1052//              bdm_assert_debug ( c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given" );
1053        }
1054
1055        //! Get cond for myself from val and cond of "Up"
1056        vec get_cond ( const vec &val_up, const vec &cond_up ) {
1057                vec tmp ( condsize );
1058                fill_cond ( val_up, cond_up, tmp );
1059                return tmp;
1060        }
1061        //! fill condition
1062        void fill_cond ( const vec &val_up, const vec &cond_up, vec& cond_out ) {
1063                bdm_assert_debug ( cond_out.length() >= condsize, "dl.fill_cond: cond_out is too small" );
1064                set_subvector ( cond_out, v2c_lo, val_up ( v2c_up ) );
1065                set_subvector ( cond_out, c2c_lo, cond_up ( c2c_up ) );
1066        }
1067        //! Fill
1068
1069};
1070
1071
1072//! \brief Combines RVs from a list of pdfs to a single one.
1073RV get_composite_rv ( const Array<shared_ptr<pdf> > &pdfs, bool checkoverlap = false );
1074
1075/*! \brief Abstract class for discrete-time sources of data.
1076
1077The class abstracts operations of:
1078\li  data aquisition,
1079\li  data-preprocessing, such as  scaling of data,
1080\li  data resampling from the task of estimation and control.
1081Moreover, for controlled systems, it is able to receive the desired control action and perform it in the next step. (Or as soon as possible).
1082
1083The DataSource has three main data interaction structures:
1084\li input, \f$ u_t \f$,
1085\li output \f$ y_t \f$,
1086\li data, \f$ d_t=[y_t,u_t, \ldots ]\f$ a collection of all inputs and outputs and possibly some internal variables too.
1087
1088*/
1089
1090class DS : public root {
1091        //! \var log_level_enums logdt
1092        //! TODO DOPLNIT
1093
1094        //! \var log_level_enums logut
1095        //! TODO DOPLNIT
1096        LOG_LEVEL(DS,logdt,logut);
1097
1098protected:
1099        //! size of data returned by \c getdata()
1100        int dtsize;
1101        //! size of data
1102        int utsize;
1103        //!Description of data returned by \c getdata().
1104        RV Drv;
1105        //!Description of data witten by by \c write().
1106        RV Urv; //
1107public:
1108        //! default constructors
1109        DS() : dtsize ( 0 ), utsize ( 0 ), Drv(), Urv(){
1110                log_level[logdt] = true;
1111                log_level[logut] = true;
1112        };
1113
1114        //! 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().
1115        virtual int max_length() {
1116                return std::numeric_limits< int >::max();
1117        }
1118        //! Returns full vector of observed data=[output, input]
1119        virtual void getdata ( vec &dt ) const = 0;
1120
1121        //! Returns data records at indices. Default is inefficent.
1122        virtual void getdata ( vec &dt, const ivec &indices ) {
1123                vec tmp(dtsize);
1124                getdata(tmp);
1125                dt = tmp(indices);
1126        };
1127
1128        //! Accepts action variable and schedule it for application.   
1129        virtual void write ( const vec &ut ) NOT_IMPLEMENTED_VOID;
1130
1131        //! Accepts action variables at specific indices
1132        virtual void write ( const vec &ut, const ivec &indices ) NOT_IMPLEMENTED_VOID;
1133
1134        //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system.
1135        virtual void step() = 0;
1136
1137        //! Register DS for logging into logger L
1138        virtual void log_register ( logger &L,  const string &prefix );
1139        //! Register DS for logging into logger L
1140        virtual void log_write ( ) const;
1141        //!access function
1142        virtual const RV& _drv() const {
1143                return Drv;
1144        }
1145        //!access function
1146        const RV& _urv() const {
1147                return Urv;
1148        }
1149
1150        //! set random variables
1151        virtual void set_drv ( const  RV &drv, const RV &urv) {
1152                Drv = drv;
1153                Urv = urv;
1154        }
1155
1156        void from_setting ( const Setting &set );
1157
1158        void validate();
1159};
1160
1161/*! \brief Bayesian Model of a system, i.e. all uncertainty is modeled by probabilities.
1162
1163This object represents exact or approximate evaluation of the Bayes rule:
1164\f[
1165f(\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})}
1166\f]
1167where:
1168 * \f$ y_t \f$ is the variable
1169Access to the resulting posterior density is via function \c posterior().
1170
1171As a "side-effect" it also evaluates log-likelihood of the data, which can be accessed via function _ll().
1172It can also evaluate predictors of future values of \f$y_t\f$, see functions epredictor() and predictor().
1173
1174Alternatively, it can evaluate posterior density with rvc replaced by the given values, \f$ c_t \f$:
1175\f[
1176f(\theta_t | c_t, d_1,\ldots,d_t) \propto  f(y_t,\theta_t|c_t,\cdot, d_1,\ldots,d_{t-1})
1177\f]
1178
1179*/
1180
1181class BM : public root {
1182        //! \var log_level_enums logfull
1183        //! TODO DOPLNIT
1184
1185        //! \var log_level_enums logevidence
1186        //! TODO DOPLNIT
1187       
1188        //! \var log_level_enums logbounds
1189        //! TODO DOPLNIT       
1190        LOG_LEVEL(BM,logfull,logevidence,logbounds);
1191
1192protected:
1193        //! Random variable of the data (optional)
1194        RV yrv;
1195        //! size of the data record
1196        int dimy;
1197        //! Name of extension variable
1198        RV rvc;
1199        //! size of the conditioning vector
1200        int dimc;
1201
1202        //!Logarithm of marginalized data likelihood.
1203        double ll;
1204        //!  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.
1205        bool evalll;
1206
1207public:
1208        //! \name Constructors
1209        //! @{
1210
1211        BM() : yrv(), dimy ( 0 ), rvc(), dimc ( 0 ), ll ( 0 ), evalll ( true ) { };
1212        //      BM ( const BM &B ) :  yrv ( B.yrv ), dimy(B.dimy), rvc ( B.rvc ),dimc(B.dimc), ll ( B.ll ), evalll ( B.evalll ) {}
1213        //! \brief Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually!
1214        //! Prototype: \code BM* _copy() const {return new BM(*this);} \endcode
1215        virtual BM* _copy() const NOT_IMPLEMENTED(NULL);
1216        //!@}
1217
1218        //! \name Mathematical operations
1219        //!@{
1220
1221        /*! \brief Incremental Bayes rule
1222        @param dt vector of input data
1223        */
1224        virtual void bayes ( const vec &yt, const vec &cond = empty_vec ) = 0;
1225        //! Batch Bayes rule (columns of Dt are observations)
1226        virtual void bayes_batch ( const mat &Dt, const vec &cond = empty_vec );
1227        //! Batch Bayes rule (columns of Dt are observations, columns of Cond are conditions)
1228        virtual void bayes_batch ( const mat &Dt, const mat &Cond );
1229        //! Evaluates predictive log-likelihood of the given data record
1230        //! I.e. marginal likelihood of the data with the posterior integrated out.
1231        //! This function evaluates only \f$ y_t \f$, condition is assumed to be the last used in bayes().
1232        //! See bdm::BM::predictor for conditional version.
1233        virtual double logpred ( const vec &yt ) const NOT_IMPLEMENTED(0.0);
1234
1235        //! Matrix version of logpred
1236        vec logpred_mat ( const mat &Yt ) const {
1237                vec tmp ( Yt.cols() );
1238                for ( int i = 0; i < Yt.cols(); i++ ) {
1239                        tmp ( i ) = logpred ( Yt.get_col ( i ) );
1240                }
1241                return tmp;
1242        }
1243
1244        //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$
1245        virtual epdf* epredictor() const NOT_IMPLEMENTED(NULL);
1246
1247        //!Constructs conditional density of 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) \f$
1248        virtual pdf* predictor() const NOT_IMPLEMENTED(NULL);
1249
1250        //!@}
1251
1252
1253        //! \name Access to attributes
1254        //!@{
1255        //! access function
1256        const RV& _rvc() const {
1257                return rvc;
1258        }
1259        //! access function
1260        int dimensionc() const {
1261                return dimc;
1262        }
1263        //! access function
1264        int dimensiony() const {
1265                return dimy;
1266        }
1267        //! access function
1268        int dimension() const {
1269                return posterior().dimension();
1270        }
1271        //! access function
1272        const RV& _rv() const {
1273                return posterior()._rv();
1274        }
1275        //! access function
1276        const RV& _yrv() const {
1277                return yrv;
1278        }
1279        //! access function
1280        void set_yrv ( const RV &rv ) {
1281                yrv = rv;
1282        }
1283        //! access function
1284        void set_rvc ( const RV &rv ) {
1285                rvc = rv;
1286        }
1287        //! access to rv of the posterior
1288        void set_rv ( const RV &rv ) {
1289                const_cast<epdf&> ( posterior() ).set_rv ( rv );
1290        }
1291        //! access function
1292        void set_dim ( int dim ) {
1293                const_cast<epdf&> ( posterior() ).set_dim ( dim );
1294        }
1295        //! return internal log-likelihood of the last data vector
1296        double _ll() const {
1297                return ll;
1298        }
1299        //! switch evaluation of log-likelihood on/off
1300        void set_evalll ( bool evl0 ) {
1301                evalll = evl0;
1302        }
1303        //! return posterior density
1304        virtual const epdf& posterior() const = 0;
1305       
1306        epdf& prior() {return const_cast<epdf&>(posterior());}
1307        //! set prior density -- same as posterior but writable
1308        virtual void set_prior(const epdf *pdf0) NOT_IMPLEMENTED_VOID;
1309       
1310        //!@}
1311
1312        //! \name Logging of results
1313        //!@{
1314
1315        //! Add all logged variables to a logger
1316        //! Log levels two digits: xy where
1317        //!  * y = 0/1 log-likelihood is to be logged
1318        //!  * x = level of the posterior (typically 0/1/2 for nothing/mean/bounds)
1319        virtual void log_register ( logger &L, const string &prefix = "" );
1320
1321        //! Save results to the given logger, details of what is stored is configured by \c LIDs and \c options
1322        virtual void log_write ( ) const;
1323
1324        //!@}
1325        void from_setting ( const Setting &set ) {
1326                shared_ptr<RV> r = UI::build<RV> ( set, "yrv", UI::optional );
1327                if ( r ) {
1328                        set_yrv ( *r );
1329                }
1330                shared_ptr<RV> r2 = UI::build<RV> ( set, "rvc", UI::optional );
1331                if ( r2 ) {
1332                        rvc =   *r2;
1333                }
1334                shared_ptr<RV> r3 = UI::build<RV> ( set, "rv", UI::optional );
1335                if ( r3 ) {
1336                        set_rv ( *r3 );
1337                }
1338
1339                UI::get ( log_level, set, "log_level", UI::optional );
1340        }
1341
1342        void to_setting ( Setting &set ) const {
1343                root::to_setting( set );
1344                UI::save( &yrv, set, "yrv" );
1345                UI::save( &rvc, set, "rvc" );           
1346                UI::save( &posterior()._rv(), set, "rv" );
1347                UI::save( log_level, set );
1348        }
1349
1350        void validate()
1351        {
1352                if ( log_level[logfull] ) {
1353                        const_cast<epdf&> ( posterior() ).log_level[epdf::logfull] = true;
1354                } else {
1355                        if ( log_level[logbounds] ) {
1356                                const_cast<epdf&> ( posterior() ).log_level[epdf::loglbound] = true;
1357                        } else {
1358                                const_cast<epdf&> ( posterior() ).log_level[epdf::logmean] = true;;
1359                        }
1360                        if ( log_level[logevidence] ) {
1361                        }
1362                }
1363        }
1364};
1365
1366//! array of pointers to epdf
1367typedef Array<shared_ptr<epdf> > epdf_array;
1368//! array of pointers to pdf
1369typedef Array<shared_ptr<pdf> > pdf_array;
1370
1371template<class EPDF>
1372vec pdf_internal<EPDF>::samplecond ( const vec &cond ) {
1373        condition ( cond );
1374        vec temp = iepdf.sample();
1375        return temp;
1376}
1377
1378template<class EPDF>
1379mat pdf_internal<EPDF>::samplecond_mat ( const vec &cond, int N ) {
1380        condition ( cond );
1381        mat temp ( dimension(), N );
1382        vec smp ( dimension() );
1383        for ( int i = 0; i < N; i++ ) {
1384                smp = iepdf.sample();
1385                temp.set_col ( i, smp );
1386        }
1387
1388        return temp;
1389}
1390
1391template<class EPDF>
1392double pdf_internal<EPDF>::evallogcond ( const vec &yt, const vec &cond ) {
1393        double tmp;
1394        condition ( cond );
1395        tmp = iepdf.evallog ( yt );
1396        return tmp;
1397}
1398
1399template<class EPDF>
1400vec pdf_internal<EPDF>::evallogcond_mat ( const mat &Yt, const vec &cond ) {
1401        condition ( cond );
1402        return iepdf.evallog_mat ( Yt );
1403}
1404
1405template<class EPDF>
1406vec pdf_internal<EPDF>::evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) {
1407        condition ( cond );
1408        return iepdf.evallog_mat ( Yt );
1409}
1410
1411}; //namespace
1412#endif // BDMBASE_H
Note: See TracBrowser for help on using the browser.