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

Revision 945, 42.0 kB (checked in by mido, 14 years ago)

patch of UI and log_levels to obtain nicer and mainly compilable source code.)

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