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 | | #include <string> |
18 | | #include <bitset> |
19 | | |
20 | | #include "../itpp_ext.h" |
21 | | #include "../bdmroot.h" |
22 | | #include "../shared_ptr.h" |
23 | | #include "user_info.h" |
24 | | |
25 | | using namespace libconfig; |
26 | | using namespace itpp; |
27 | | using namespace std; |
28 | | |
29 | | namespace bdm { |
30 | | //! Structure of RV, i.e. RVs expanded into a flat list of IDs, used for debugging. |
31 | | class str { |
32 | | public: |
33 | | //! vector id ids (non-unique!) |
34 | | ivec ids; |
35 | | //! vector of times |
36 | | ivec times; |
37 | | //!Default constructor |
38 | | str ( ivec ids0, ivec times0 ) : ids ( ids0 ), times ( times0 ) { |
39 | | bdm_assert ( times0.length() == ids0.length(), "Incompatible input" ); |
40 | | }; |
41 | | }; |
42 | | |
43 | | /*! |
44 | | * \brief Class representing variables, most often random variables |
45 | | |
46 | | The 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. |
47 | | |
48 | | The class is implemented using global variables to assure uniqueness of description: |
49 | | |
50 | | In is a vector |
51 | | \dot |
52 | | digraph datalink { |
53 | | rankdir=LR; |
54 | | subgraph cluster0 { |
55 | | node [shape=record]; |
56 | | label = "MAP \n std::map<string,int>"; |
57 | | map [label="{{\"a\"| \"b\" | \"c\"} | {<3> 3 |<1> 1|<2> 2}}"]; |
58 | | color = "white" |
59 | | } |
60 | | subgraph cluster1{ |
61 | | node [shape=record]; |
62 | | label = "NAMES"; |
63 | | names [label="{<1> \"b\" | <2> \"c\" | <3>\"a\" }"]; |
64 | | color = "white" |
65 | | } |
66 | | subgraph cluster2{ |
67 | | node [shape=record]; |
68 | | label = "SIZES"; |
69 | | labelloc = b; |
70 | | sizes [label="{<1>1 |<2> 4 |<3> 1}"]; |
71 | | color = "white" |
72 | | } |
73 | | map:1 -> names:1; |
74 | | map:1 -> sizes:1; |
75 | | map:3 -> names:3; |
76 | | map:3 -> sizes:3; |
77 | | } |
78 | | \enddot |
79 | | */ |
80 | | |
81 | | class RV : public root { |
82 | | private: |
83 | | typedef std::map<string, int> str2int_map; |
84 | | |
85 | | //! Internal global variable storing sizes of RVs |
86 | | static ivec SIZES; |
87 | | //! Internal global variable storing names of RVs |
88 | | static Array<string> NAMES; |
89 | | |
90 | | //! TODO |
91 | | const static int BUFFER_STEP; |
92 | | |
93 | | //! TODO |
94 | | static str2int_map MAP; |
95 | | |
96 | | public: |
97 | | |
98 | | protected: |
99 | | //! size of the data vector |
100 | | int dsize; |
101 | | //! number of individual rvs |
102 | | int len; |
103 | | //! Vector of unique IDs |
104 | | ivec ids; |
105 | | //! Vector of shifts from current time |
106 | | ivec times; |
107 | | |
108 | | private: |
109 | | enum enum_dummy {dummy}; |
110 | | |
111 | | //! auxiliary function used in constructor |
112 | | void init( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times ); |
113 | | |
114 | | //! auxiliary function assigning unique integer index related to the passed name and size of the random variable |
115 | | int assign_id( const string &name, int size ); |
116 | | |
117 | | //! Private constructor from IDs, potentially dangerous since all ids must be valid! |
118 | | //! dummy is there to prevent confusion with RV(" string"); |
119 | | explicit RV ( const ivec &ids0, enum_dummy dum ) : dsize ( 0 ), len ( ids0.length() ), ids ( ids0 ), times ( zeros_i ( ids0.length() ) ) { |
120 | | dsize = countsize(); |
121 | | } |
122 | | public: |
123 | | //! \name Constructors |
124 | | //!@{ |
125 | | |
126 | | //! Full constructor |
127 | | RV ( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times ) { |
128 | | init ( in_names, in_sizes, in_times ); |
129 | | } |
130 | | |
131 | | //! Constructor with times=0 |
132 | | RV ( const Array<std::string> &in_names, const ivec &in_sizes ) { |
133 | | init ( in_names, in_sizes, zeros_i ( in_names.length() ) ); |
134 | | } |
135 | | |
136 | | //! Constructor with sizes=1, times=0 |
137 | | RV ( const Array<std::string> &in_names ) { |
138 | | init ( in_names, ones_i ( in_names.length() ), zeros_i ( in_names.length() ) ); |
139 | | } |
140 | | |
141 | | //! Constructor of empty RV |
142 | | RV() : dsize ( 0 ), len ( 0 ), ids ( 0 ), times ( 0 ) {} |
143 | | |
144 | | //! Constructor of a single RV with given id |
145 | | RV ( string name, 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 | | }; |
292 | | UIREGISTER ( RV ); |
293 | | SHAREDPTR ( RV ); |
294 | | |
295 | | //! Concat two random variables |
296 | | RV concat ( const RV &rv1, const RV &rv2 ); |
297 | | |
298 | | /*! |
299 | | @brief Class for storing results (and semi-results) of an experiment |
300 | | |
301 | | This 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 | | */ |
303 | | class logger : public root { |
304 | | protected: |
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 | | //!separator of prefixes of entries |
310 | | const string separator; |
311 | | //! Root Setting for storing Settings |
312 | | Config setting_conf; |
313 | | //! list of Settings for specific ids |
314 | | Array<Setting*> settings; |
315 | | public: |
316 | | //!Default constructor |
317 | | logger ( const string separator0 ) : entries ( 0 ), names ( 0 ), separator ( separator0 ) {} |
318 | | |
319 | | //! returns an identifier which will be later needed for calling the \c logit() function |
320 | | //! For empty RV it returns -1, this entry will be ignored by \c logit(). |
321 | | virtual int add_vector ( const RV &rv, string prefix = "" ); |
322 | | |
323 | | virtual int add_setting ( const string &prefix ); |
324 | | |
325 | | //! log this vector |
326 | | virtual void log_vector ( int id, const vec &v ) = 0; |
327 | | |
328 | | virtual Setting & log_to_setting ( int id ) { |
329 | | return settings ( id )->add ( Setting::TypeGroup ); |
330 | | } |
331 | | //! log this double |
332 | | virtual void logit ( int id, const double &d ) = 0; |
333 | | |
334 | | //! Shifts storage position for another time step. |
335 | | virtual void step() = 0; |
336 | | |
337 | | //! Finalize storing information |
338 | | virtual void finalize() {}; |
339 | | |
340 | | //! Initialize the storage |
341 | | virtual void init() {}; |
342 | | |
343 | | //!separator of prefixes for this logger |
344 | | const string& prefix_sep() { |
345 | | return separator; |
346 | | } |
347 | | }; |
348 | | |
349 | | |
350 | | //! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv |
351 | | class fnc : public root { |
352 | | protected: |
353 | | //! Length of the output vector |
354 | | int dimy; |
355 | | //! Length of the input vector |
356 | | int dimc; |
357 | | public: |
358 | | //!default constructor |
359 | | fnc() {}; |
360 | | //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond |
361 | | virtual vec eval ( const vec &cond ) { |
362 | | return vec ( 0 ); |
363 | | }; |
364 | | |
365 | | //! function substitutes given value into an appropriate position |
366 | | virtual void condition ( const vec &val ) {}; |
367 | | |
368 | | //! access function |
369 | | int dimension() const { |
370 | | return dimy; |
371 | | } |
372 | | //! access function |
373 | | int dimensionc() const { |
374 | | return dimc; |
375 | | } |
376 | | }; |
377 | | |
378 | | class epdf; |
379 | | |
380 | | //! 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. |
381 | | class pdf : public root { |
382 | | protected: |
383 | | //!dimension of the condition |
384 | | int dimc; |
385 | | |
386 | | //! random variable in condition |
387 | | RV rvc; |
388 | | |
389 | | //! dimension of random variable |
390 | | int dim; |
391 | | |
392 | | //! random variable |
393 | | RV rv; |
394 | | |
395 | | public: |
396 | | //! \name Constructors |
397 | | //! @{ |
398 | | |
399 | | pdf() : dimc ( 0 ), rvc(), dim ( 0 ), rv() { } |
400 | | |
401 | | pdf ( const pdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), dim ( m.dim ), rv ( m.rv ) { } |
402 | | |
403 | | //!@} |
404 | | |
405 | | //! \name Matematical operations |
406 | | //!@{ |
407 | | |
408 | | //! 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 |
409 | | virtual vec samplecond ( const vec &cond ) = 0; |
410 | | |
411 | | //! 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 |
412 | | virtual mat samplecond_mat ( const vec &cond, int N ); |
413 | | |
414 | | //! Shortcut for conditioning and evaluation of the internal epdf. In some cases, this operation can be implemented efficiently. |
415 | | virtual double evallogcond ( const vec &yt, const vec &cond ) = 0; |
416 | | |
417 | | //! Matrix version of evallogcond |
418 | | virtual vec evallogcond_mat ( const mat &Yt, const vec &cond ) { |
419 | | vec v ( Yt.cols() ); |
420 | | for ( int i = 0; i < Yt.cols(); i++ ) { |
421 | | v ( i ) = evallogcond ( Yt.get_col ( i ), cond ); |
422 | | } |
423 | | return v; |
424 | | } |
425 | | |
426 | | //! Array<vec> version of evallogcond |
427 | | virtual vec evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) { |
428 | | vec v ( Yt.length() ); |
429 | | for ( int i = 0; i < Yt.length(); i++ ) { |
430 | | v ( i ) = evallogcond ( Yt( i ), cond ); |
431 | | } |
432 | | return v; |
433 | | } |
434 | | |
435 | | //! \name Access to attributes |
436 | | //! @{ |
437 | | |
438 | | const RV& _rv() const { |
439 | | return rv; |
440 | | } |
441 | | const RV& _rvc() const { |
442 | | return rvc; |
443 | | } |
444 | | |
445 | | int dimension() const { |
446 | | return dim; |
447 | | } |
448 | | int dimensionc() { |
449 | | return dimc; |
450 | | } |
451 | | |
452 | | //! access function |
453 | | void set_dim ( int d ) { |
454 | | dim = d; |
455 | | } |
456 | | //! access function |
457 | | void set_dimc ( int d ) { |
458 | | dimc = d; |
459 | | } |
460 | | //! Load from structure with elements: |
461 | | //! \code |
462 | | //! { class = "pdf_offspring", |
463 | | //! rv = {class="RV", names=(...),}; // RV describing meaning of random variable |
464 | | //! rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition |
465 | | //! // elements of offsprings |
466 | | //! } |
467 | | //! \endcode |
468 | | //!@} |
469 | | void from_setting ( const Setting &set ); |
470 | | |
471 | | void to_setting ( Setting &set ) const; |
472 | | //!@} |
473 | | |
474 | | //! \name Connection to other objects |
475 | | //!@{ |
476 | | void set_rvc ( const RV &rvc0 ) { |
477 | | rvc = rvc0; |
478 | | } |
479 | | void set_rv ( const RV &rv0 ) { |
480 | | rv = rv0; |
481 | | } |
482 | | |
483 | | //! Names of variables stored in RV are considered to be valid only if their size match size of the parameters (dim). |
484 | | bool isnamed() const { |
485 | | return ( dim == rv._dsize() ) && ( dimc == rvc._dsize() ); |
486 | | } |
487 | | //!@} |
488 | | }; |
489 | | SHAREDPTR ( pdf ); |
490 | | |
491 | | //! Probability density function with numerical statistics, e.g. posterior density. |
492 | | class epdf : public pdf { |
493 | | |
494 | | public: |
495 | | /*! \name Constructors |
496 | | Construction of each epdf should support two types of constructors: |
497 | | \li empty constructor, |
498 | | \li copy constructor, |
499 | | |
500 | | The following constructors should be supported for convenience: |
501 | | \li constructor followed by calling \c set_parameters() |
502 | | \li constructor accepting random variables calling \c set_rv() |
503 | | |
504 | | All internal data structures are constructed as empty. Their values (including sizes) will be set by method \c set_parameters(). This way references can be initialized in constructors. |
505 | | @{*/ |
506 | | epdf() {}; |
507 | | epdf ( const epdf &e ) : pdf ( e ) {}; |
508 | | |
509 | | virtual void validate (int dim0){ |
510 | | dim = dim0; |
511 | | } |
512 | | |
513 | | //!@} |
514 | | |
515 | | //! \name Matematical Operations |
516 | | //!@{ |
517 | | |
518 | | //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$ |
519 | | virtual vec sample() const = 0; |
520 | | |
521 | | //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$ from density \f$ f_x(rv)\f$ |
522 | | virtual mat sample_mat ( int N ) const; |
523 | | |
524 | | //! Compute log-probability of argument \c val |
525 | | //! In case the argument is out of suport return -Infinity |
526 | | virtual double evallog ( const vec &val ) const = 0; |
527 | | |
528 | | //! Compute log-probability of multiple values argument \c val |
529 | | virtual vec evallog_mat ( const mat &Val ) const; |
530 | | |
531 | | //! Compute log-probability of multiple values argument \c val |
532 | | virtual vec evallog_mat ( const Array<vec> &Avec ) const; |
533 | | |
534 | | //! Return conditional density on the given RV, the remaining rvs will be in conditioning |
535 | | virtual shared_ptr<pdf> condition ( const RV &rv ) const; |
536 | | |
537 | | //! Return marginal density on the given RV, the remainig rvs are intergrated out |
538 | | virtual shared_ptr<epdf> marginal ( const RV &rv ) const; |
539 | | |
540 | | virtual vec mean() const = 0; |
541 | | |
542 | | //! return expected variance (not covariance!) |
543 | | virtual vec variance() const = 0; |
544 | | |
545 | | //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default |
546 | | virtual void qbounds ( vec &lb, vec &ub, double percentage = 0.95 ) const { |
547 | | vec mea = mean(); |
548 | | vec std = sqrt ( variance() ); |
549 | | lb = mea - 2 * std; |
550 | | ub = mea + 2 * std; |
551 | | }; |
552 | | //!@} |
553 | | |
554 | | //! \name Connection to other classes |
555 | | //! Description of the random quantity via attribute \c rv is optional. |
556 | | //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization |
557 | | //! and \c conditioning \c rv has to be set. NB: |
558 | | //! @{ |
559 | | |
560 | | //! store values of the epdf on the following levels: |
561 | | //! #1 mean |
562 | | //! #2 mean + lower & upper bound |
563 | | void log_register ( logger &L, const string &prefix ); |
564 | | |
565 | | void log_write() const; |
566 | | //!@} |
567 | | |
568 | | //! \name Access to attributes |
569 | | //! @{ |
570 | | |
571 | | //! Load from structure with elements: |
572 | | //! \code |
573 | | //! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable |
574 | | //! // elements of offsprings |
575 | | //! } |
576 | | //! \endcode |
577 | | //!@} |
578 | | void from_setting ( const Setting &set ) { |
579 | | shared_ptr<RV> r = UI::build<RV> ( set, "rv", UI::optional ); |
580 | | if ( r ) { |
581 | | set_rv ( *r ); |
582 | | } |
583 | | } |
584 | | |
585 | | void to_setting ( Setting &set ) const { |
586 | | // we do not want to store rvc, therfore, pdf::to_setting( set ) is omitted |
587 | | root::to_setting(set); |
588 | | |
589 | | UI::save( &rv, set, "rv" ); |
590 | | } |
591 | | |
592 | | vec samplecond ( const vec &cond ) { |
593 | | return sample(); |
594 | | } |
595 | | double evallogcond ( const vec &val, const vec &cond ) { |
596 | | return evallog ( val ); |
597 | | } |
598 | | }; |
599 | | SHAREDPTR ( epdf ); |
600 | | |
601 | | //! pdf with internal epdf that is modified by function \c condition |
602 | | template <class EPDF> |
603 | | class pdf_internal: public pdf { |
604 | | protected : |
605 | | //! Internal epdf used for sampling |
606 | | EPDF iepdf; |
607 | | public: |
608 | | //! constructor |
609 | | pdf_internal() : pdf(), iepdf() { |
610 | | } |
611 | | |
612 | | //! Update \c iepdf so that it represents this pdf conditioned on \c rvc = cond |
613 | | //! This function provides convenient reimplementation in offsprings |
614 | | virtual void condition ( const vec &cond ) = 0; |
615 | | |
616 | | //!access function to iepdf |
617 | | EPDF& e() { |
618 | | return iepdf; |
619 | | } |
620 | | |
621 | | //! Reimplements samplecond using \c condition() |
622 | | vec samplecond ( const vec &cond ); |
623 | | //! Reimplements evallogcond using \c condition() |
624 | | double evallogcond ( const vec &val, const vec &cond ); |
625 | | //! Efficient version of evallogcond for matrices |
626 | | virtual vec evallogcond_mat ( const mat &Dt, const vec &cond ); |
627 | | //! Efficient version of evallogcond for Array<vec> |
628 | | virtual vec evallogcond_mat ( const Array<vec> &Dt, const vec &cond ); |
629 | | //! Efficient version of samplecond |
630 | | virtual mat samplecond_mat ( const vec &cond, int N ); |
631 | | |
632 | | void validate() { |
633 | | iepdf.validate(); |
634 | | if ( rv._dsize() < iepdf._rv()._dsize() ) { |
635 | | rv = iepdf._rv(); |
636 | | }; |
637 | | dim = iepdf.dimension(); |
638 | | } |
639 | | }; |
640 | | |
641 | | /*! \brief DataLink is a connection between two data vectors Up and Down |
642 | | |
643 | | Up can be longer than Down. Down must be fully present in Up (TODO optional) |
644 | | See chart: |
645 | | \dot |
646 | | digraph datalink { |
647 | | node [shape=record]; |
648 | | subgraph cluster0 { |
649 | | label = "Up"; |
650 | | up [label="<1>|<2>|<3>|<4>|<5>"]; |
651 | | color = "white" |
652 | | } |
653 | | subgraph cluster1{ |
654 | | label = "Down"; |
655 | | labelloc = b; |
656 | | down [label="<1>|<2>|<3>"]; |
657 | | color = "white" |
658 | | } |
659 | | up:1 -> down:1; |
660 | | up:3 -> down:2; |
661 | | up:5 -> down:3; |
662 | | } |
663 | | \enddot |
664 | | |
665 | | */ |
666 | | class datalink { |
667 | | protected: |
668 | | //! Remember how long val should be |
669 | | int downsize; |
670 | | |
671 | | //! Remember how long val of "Up" should be |
672 | | int upsize; |
673 | | |
674 | | //! val-to-val link, indices of the upper val |
675 | | ivec v2v_up; |
676 | | |
677 | | public: |
678 | | //! Constructor |
679 | | datalink() : downsize ( 0 ), upsize ( 0 ) { } |
680 | | |
681 | | //! Convenience constructor |
682 | | datalink ( const RV &rv, const RV &rv_up ) { |
683 | | set_connection ( rv, rv_up ); |
684 | | } |
685 | | |
686 | | //! set connection, rv must be fully present in rv_up |
687 | | virtual void set_connection ( const RV &rv, const RV &rv_up ); |
688 | | |
689 | | //! set connection using indices |
690 | | virtual void set_connection ( int ds, int us, const ivec &upind ); |
691 | | |
692 | | //! Get val for myself from val of "Up" |
693 | | vec pushdown ( const vec &val_up ) { |
694 | | vec tmp ( downsize ); |
695 | | filldown ( val_up, tmp ); |
696 | | return tmp; |
697 | | } |
698 | | //! Get val for vector val_down from val of "Up" |
699 | | virtual void filldown ( const vec &val_up, vec &val_down ) { |
700 | | bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); |
701 | | val_down = val_up ( v2v_up ); |
702 | | } |
703 | | //! Fill val of "Up" by my pieces |
704 | | virtual void pushup ( vec &val_up, const vec &val ) { |
705 | | bdm_assert_debug ( downsize == val.length(), "Wrong val" ); |
706 | | bdm_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); |
707 | | set_subvector ( val_up, v2v_up, val ); |
708 | | } |
709 | | //! access functions |
710 | | int _upsize() { |
711 | | return upsize; |
712 | | } |
713 | | //! access functions |
714 | | int _downsize() { |
715 | | return downsize; |
716 | | } |
717 | | //! for future use |
718 | | virtual ~datalink() {} |
719 | | }; |
720 | | |
721 | | /*! Extension of datalink to fill only part of Down |
722 | | */ |
723 | | class datalink_part : public datalink { |
724 | | protected: |
725 | | //! indeces of values in vector downsize |
726 | | ivec v2v_down; |
727 | | public: |
728 | | void set_connection ( const RV &rv, const RV &rv_up ); |
729 | | //! Get val for vector val_down from val of "Up" |
730 | | void filldown ( const vec &val_up, vec &val_down ) { |
731 | | set_subvector ( val_down, v2v_down, val_up ( v2v_up ) ); |
732 | | } |
733 | | }; |
734 | | |
735 | | /*! \brief Datalink that buffers delayed values - do not forget to call step() |
736 | | |
737 | | Up is current data, Down is their subset with possibly delayed values |
738 | | */ |
739 | | class datalink_buffered: public datalink_part { |
740 | | protected: |
741 | | //! History, ordered as \f$[Up_{t-1},Up_{t-2}, \ldots]\f$ |
742 | | vec history; |
743 | | //! rv of the history |
744 | | RV Hrv; |
745 | | //! h2v : indeces in down |
746 | | ivec h2v_down; |
747 | | //! h2v : indeces in history |
748 | | ivec h2v_hist; |
749 | | //! v2h: indeces of up too be pushed to h |
750 | | ivec v2h_up; |
751 | | public: |
752 | | |
753 | | datalink_buffered() : datalink_part(), history ( 0 ), h2v_down ( 0 ), h2v_hist ( 0 ) {}; |
754 | | //! push current data to history |
755 | | void store_data ( const vec &val_up ) { |
756 | | if ( v2h_up.length() > 0 ) { |
757 | | history.shift_right ( 0, v2h_up.length() ); |
758 | | history.set_subvector ( 0, val_up ( v2h_up ) ); |
759 | | } |
760 | | } |
761 | | //! Get val for myself from val of "Up" |
762 | | vec pushdown ( const vec &val_up ) { |
763 | | vec tmp ( downsize ); |
764 | | filldown ( val_up, tmp ); |
765 | | return tmp; |
766 | | } |
767 | | |
768 | | void filldown ( const vec &val_up, vec &val_down ) { |
769 | | bdm_assert_debug ( val_down.length() >= downsize, "short val_down" ); |
770 | | |
771 | | set_subvector ( val_down, v2v_down, val_up ( v2v_up ) ); // copy direct values |
772 | | set_subvector ( val_down, h2v_down, history ( h2v_hist ) ); // copy delayed values |
773 | | } |
774 | | |
775 | | void set_connection ( const RV &rv, const RV &rv_up ); |
776 | | |
777 | | //! set history of variable given by \c rv1 to values of \c hist. |
778 | | void set_history ( const RV& rv1, const vec &hist0 ); |
779 | | }; |
780 | | |
781 | | //! buffered datalink from 2 vectors to 1 |
782 | | class datalink_2to1_buffered { |
783 | | protected: |
784 | | //! link 1st vector to down |
785 | | datalink_buffered dl1; |
786 | | //! link 2nd vector to down |
787 | | datalink_buffered dl2; |
788 | | public: |
789 | | //! set connection between RVs |
790 | | void set_connection ( const RV &rv, const RV &rv_up1, const RV &rv_up2 ) { |
791 | | dl1.set_connection ( rv, rv_up1 ); |
792 | | dl2.set_connection ( rv, rv_up2 ); |
793 | | } |
794 | | //! fill values of down from the values of the two up vectors |
795 | | void filldown ( const vec &val1, const vec &val2, vec &val_down ) { |
796 | | bdm_assert_debug ( val_down.length() >= dl1._downsize() + dl2._downsize(), "short val_down" ); |
797 | | dl1.filldown ( val1, val_down ); |
798 | | dl2.filldown ( val2, val_down ); |
799 | | } |
800 | | //! update buffer |
801 | | void step ( const vec &dt, const vec &ut ) { |
802 | | dl1.store_data ( dt ); |
803 | | dl2.store_data ( ut ); |
804 | | } |
805 | | }; |
806 | | |
807 | | |
808 | | |
809 | | //! Data link with a condition. |
810 | | class datalink_m2e: public datalink { |
811 | | protected: |
812 | | //! Remember how long cond should be |
813 | | int condsize; |
814 | | |
815 | | //!upper_val-to-local_cond link, indices of the upper val |
816 | | ivec v2c_up; |
817 | | |
818 | | //!upper_val-to-local_cond link, indices of the local cond |
819 | | ivec v2c_lo; |
820 | | |
821 | | public: |
822 | | //! Constructor |
823 | | datalink_m2e() : condsize ( 0 ) { } |
824 | | |
825 | | //! Set connection between vectors |
826 | | void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up ); |
827 | | |
828 | | //!Construct condition |
829 | | vec get_cond ( const vec &val_up ); |
830 | | |
831 | | //! Copy corresponding values to Up.condition |
832 | | void pushup_cond ( vec &val_up, const vec &val, const vec &cond ); |
833 | | }; |
834 | | |
835 | | //!DataLink is a connection between pdf and its superordinate (Up) |
836 | | //! This class links |
837 | | class datalink_m2m: public datalink_m2e { |
838 | | protected: |
839 | | //!cond-to-cond link, indices of the upper cond |
840 | | ivec c2c_up; |
841 | | //!cond-to-cond link, indices of the local cond |
842 | | ivec c2c_lo; |
843 | | |
844 | | public: |
845 | | //! Constructor |
846 | | datalink_m2m() {}; |
847 | | //! Set connection between the vectors |
848 | | void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) { |
849 | | datalink_m2e::set_connection ( rv, rvc, rv_up ); |
850 | | //establish c2c connection |
851 | | rvc.dataind ( rvc_up, c2c_lo, c2c_up ); |
852 | | // bdm_assert_debug ( c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given" ); |
853 | | } |
854 | | |
855 | | //! Get cond for myself from val and cond of "Up" |
856 | | vec get_cond ( const vec &val_up, const vec &cond_up ) { |
857 | | vec tmp ( condsize ); |
858 | | fill_cond ( val_up, cond_up, tmp ); |
859 | | return tmp; |
860 | | } |
861 | | //! fill condition |
862 | | void fill_cond ( const vec &val_up, const vec &cond_up, vec& cond_out ) { |
863 | | bdm_assert_debug ( cond_out.length() >= condsize, "dl.fill_cond: cond_out is too small" ); |
864 | | set_subvector ( cond_out, v2c_lo, val_up ( v2c_up ) ); |
865 | | set_subvector ( cond_out, c2c_lo, cond_up ( c2c_up ) ); |
866 | | } |
867 | | //! Fill |
868 | | |
869 | | }; |
870 | | |
871 | | |
872 | | //! \brief Combines RVs from a list of pdfs to a single one. |
873 | | RV get_composite_rv ( const Array<shared_ptr<pdf> > &pdfs, bool checkoverlap = false ); |
874 | | |
875 | | /*! \brief Abstract class for discrete-time sources of data. |
876 | | |
877 | | The class abstracts operations of: |
878 | | \li data aquisition, |
879 | | \li data-preprocessing, such as scaling of data, |
880 | | \li data resampling from the task of estimation and control. |
881 | | Moreover, for controlled systems, it is able to receive the desired control action and perform it in the next step. (Or as soon as possible). |
882 | | |
883 | | The DataSource has three main data interaction structures: |
884 | | \li input, \f$ u_t \f$, |
885 | | \li output \f$ y_t \f$, |
886 | | \li data, \f$ d_t=[y_t,u_t, \ldots ]\f$ a collection of all inputs and outputs and possibly some internal variables too. |
887 | | |
888 | | */ |
889 | | |
890 | | class DS : public root { |
891 | | protected: |
892 | | //! size of data returned by \c getdata() |
893 | | int dtsize; |
894 | | //! size of data |
895 | | int utsize; |
896 | | //!size of output |
897 | | int ytsize; |
898 | | //!Description of data returned by \c getdata(). |
899 | | RV Drv; |
900 | | //!Description of data witten by by \c write(). |
901 | | RV Urv; // |
902 | | //!Description of output data |
903 | | RV Yrv; // |
904 | | public: |
905 | | //! default constructors |
906 | | DS() : dtsize ( 0 ), utsize ( 0 ), ytsize ( 0 ), Drv(), Urv(), Yrv() { |
907 | | log_level = 1; |
908 | | }; |
909 | | |
910 | | //! 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(). |
911 | | virtual int max_length() { |
912 | | return std::numeric_limits< int >::max(); |
913 | | } |
914 | | //! Returns full vector of observed data=[output, input] |
915 | | virtual void getdata ( vec &dt ) const = 0; |
916 | | |
917 | | //! Returns data records at indeces. |
918 | | virtual void getdata ( vec &dt, const ivec &indeces ) = 0; |
919 | | |
920 | | //! Accepts action variable and schedule it for application. |
921 | | virtual void write ( const vec &ut ) = 0; |
922 | | |
923 | | //! Accepts action variables at specific indeces |
924 | | virtual void write ( const vec &ut, const ivec &indeces ) = 0; |
925 | | |
926 | | //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system. |
927 | | virtual void step() = 0; |
928 | | |
929 | | //! Register DS for logging into logger L |
930 | | virtual void log_register ( logger &L, const string &prefix ); |
931 | | //! Register DS for logging into logger L |
932 | | virtual void log_write ( ) const; |
933 | | //!access function |
934 | | virtual const RV& _drv() const { |
935 | | return Drv; |
936 | | } |
937 | | //!access function |
938 | | const RV& _urv() const { |
939 | | return Urv; |
940 | | } |
941 | | //!access function |
942 | | const RV& _yrv() const { |
943 | | return Yrv; |
944 | | } |
945 | | //! set random variables |
946 | | virtual void set_drv ( const RV &yrv, const RV &urv ) { |
947 | | Yrv = yrv; |
948 | | Drv = concat ( yrv, urv ); |
949 | | Urv = urv; |
950 | | } |
951 | | }; |
952 | | |
953 | | /*! \brief Bayesian Model of a system, i.e. all uncertainty is modeled by probabilities. |
954 | | |
955 | | This object represents exact or approximate evaluation of the Bayes rule: |
956 | | \f[ |
957 | | f(\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})} |
958 | | \f] |
959 | | where: |
960 | | * \f$ y_t \f$ is the variable |
961 | | Access to the resulting posterior density is via function \c posterior(). |
962 | | |
963 | | As a "side-effect" it also evaluates log-likelihood of the data, which can be accessed via function _ll(). |
964 | | It can also evaluate predictors of future values of \f$y_t\f$, see functions epredictor() and predictor(). |
965 | | |
966 | | Alternatively, it can evaluate posterior density with rvc replaced by the given values, \f$ c_t \f$: |
967 | | \f[ |
968 | | f(\theta_t | c_t, d_1,\ldots,d_t) \propto f(y_t,\theta_t|c_t,\cdot, d_1,\ldots,d_{t-1}) |
969 | | \f] |
970 | | |
971 | | |
972 | | */ |
973 | | |
974 | | #ifndef BDMLIB |
975 | | // MUZEME INTERNE POUZIVAT ENUMY, A KLIDNE MENIT JEJICH PORADI, DIKY TOMUHLE MAKRU SE VZDY NAMAPUJI NA TY SPRAVNE STRINGY |
976 | | #define DEFINED_OPTIONS(...) enum defined_options { __VA_ARGS__ }; const Array<string> logged_options::names( "{"#__VA_ARGS__"}" ) |
977 | | // TODO: ROZPARESUJE TO KONSTRUKTOR ARRAYE NA JEDNOTLIVE STRINGY?? NUTNO OTESTOVAT!! |
978 | | #else |
979 | | #define DEFINED_OPTIONS(...) enum defined_options { __VA_ARGS__ }; |
980 | | #endif |
981 | | |
982 | | enum defined_options; |
983 | | |
984 | | class logged_options : public root |
985 | | // TODO: HA, TADY TO MAME!! POKUD ZDE CHCEME TEZ UZIVAT FROMSETTING A TOSETTING, NEMUZOU BYT LOGOVACI |
986 | | // VECI PRIMO V ROOTU.. RESENIM BUDE ZREJME KOMPOZICE - FUNKCNOST SOUVISEJICI S LOGGERAMA UMISTENA V ROOTU |
987 | | // PREJDE DO TETO TRIDY, A KDO BUDE MIT ZAJEM O NAPOJENI NA LOGGERY MUSI OBSAHOVAT LOGGED_OPTIONS INSTANCI... |
988 | | // TZN. TRIDU LOGGED OPTIONS BUDE JESTE TREBA LEHCE ROZSIRIT.. |
989 | | // KOMPOZICE TAKY UMOZNI NEKOLIK RUZNYCH LOGGERU PRO JEDEN OBJEKT.. PROSTE BUDE OBSHOVAT NEKOLIK RUZNYCH |
990 | | // LOGGED_OPTIONS INSTANCI NAPOJENYCH NA RUZNE LOGGERY.. HMM, ALE TO JE TREBA JESTE DOMYSLET.) |
991 | | { |
992 | | private: |
993 | | bitset<32> values; |
994 | | |
995 | | static const Array<string> names; |
996 | | |
997 | | public: |
998 | | |
999 | | bool operator [] (const defined_options &option ) |
1000 | | { |
1001 | | return values[option]; |
1002 | | } |
1003 | | |
1004 | | void from_setting ( const Setting &set ) |
1005 | | { |
1006 | | values.reset(); |
1007 | | Array<string> true_options; |
1008 | | UI::get( true_options, set ); |
1009 | | for( int i = 0; i < true_options.length(); i++ ) |
1010 | | for( int j = 0; j < names.length(); j++ ) |
1011 | | if( true_options(i) == names(j) ) |
1012 | | { |
1013 | | values[j] = true; |
1014 | | break; |
1015 | | } // TODO kdyz ho to vubec nenajde, nic se nedeje.. coz radeji vyhodit UI vyjimku??! |
1016 | | } |
1017 | | |
1018 | | void to_setting( Setting &set ) const |
1019 | | { |
1020 | | Array<string> true_options( values.count() ); |
1021 | | int true_options_count = 0; |
1022 | | for( unsigned int i = 0; i < values.size(); i++ ) |
1023 | | if( values[i] ) |
1024 | | true_options( true_options_count++ ) = names(i); |
1025 | | UI::save( true_options, set ); |
1026 | | } |
1027 | | }; |
1028 | | UIREGISTER(logged_options); |
1029 | | DEFINED_OPTIONS(bounds,likelyhood,full); |
1030 | | |
1031 | | |
1032 | | class BM : public root { |
1033 | | protected: |
1034 | | //! Random variable of the data (optional) |
1035 | | RV yrv; |
1036 | | //! size of the data record |
1037 | | int dimy; |
1038 | | //! Name of extension variable |
1039 | | RV rvc; |
1040 | | //! size of the conditioning vector |
1041 | | int dimc; |
1042 | | |
1043 | | //!Logarithm of marginalized data likelihood. |
1044 | | double ll; |
1045 | | //! 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. |
1046 | | bool evalll; |
1047 | | |
1048 | | public: |
1049 | | //! \name Constructors |
1050 | | //! @{ |
1051 | | |
1052 | | BM() : yrv(), dimy ( 0 ), rvc(), dimc ( 0 ), ll ( 0 ), evalll ( true ) { }; |
1053 | | // BM ( const BM &B ) : yrv ( B.yrv ), dimy(B.dimy), rvc ( B.rvc ),dimc(B.dimc), ll ( B.ll ), evalll ( B.evalll ) {} |
1054 | | //! \brief Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually! |
1055 | | //! Prototype: \code BM* _copy() const {return new BM(*this);} \endcode |
1056 | | virtual BM* _copy() const { return NULL; }; // TODO NEBUDE TU TAKY LEPSI BDM_ERROR??! |
1057 | | //!@} |
1058 | | |
1059 | | //! \name Mathematical operations |
1060 | | //!@{ |
1061 | | |
1062 | | /*! \brief Incremental Bayes rule |
1063 | | @param dt vector of input data |
1064 | | */ |
1065 | | virtual void bayes ( const vec &yt, const vec &cond = empty_vec ) = 0; |
1066 | | //! Batch Bayes rule (columns of Dt are observations) |
1067 | | virtual void bayes_batch ( const mat &Dt, const vec &cond = empty_vec ); |
1068 | | //! Batch Bayes rule (columns of Dt are observations, columns of Cond are conditions) |
1069 | | virtual void bayes_batch ( const mat &Dt, const mat &Cond ); |
1070 | | //! Evaluates predictive log-likelihood of the given data record |
1071 | | //! I.e. marginal likelihood of the data with the posterior integrated out. |
1072 | | //! This function evaluates only \f$ y_t \f$, condition is assumed to be the last used in bayes(). |
1073 | | //! See bdm::BM::predictor for conditional version. |
1074 | | virtual double logpred ( const vec &yt ) const = 0; |
1075 | | |
1076 | | //! Matrix version of logpred |
1077 | | vec logpred_mat ( const mat &Yt ) const { |
1078 | | vec tmp ( Yt.cols() ); |
1079 | | for ( int i = 0; i < Yt.cols(); i++ ) { |
1080 | | tmp ( i ) = logpred ( Yt.get_col ( i ) ); |
1081 | | } |
1082 | | return tmp; |
1083 | | } |
1084 | | |
1085 | | //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$ |
1086 | | virtual epdf* epredictor() const = 0; |
1087 | | |
1088 | | //!Constructs conditional density of 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) \f$ |
1089 | | virtual pdf* predictor() const = 0; |
1090 | | |
1091 | | //!@} |
1092 | | |
1093 | | |
1094 | | //! \name Access to attributes |
1095 | | //!@{ |
1096 | | //! access function |
1097 | | const RV& _rvc() const { |
1098 | | return rvc; |
1099 | | } |
1100 | | //! access function |
1101 | | int dimensionc() const { |
1102 | | return dimc; |
1103 | | } |
1104 | | //! access function |
1105 | | int dimensiony() const { |
1106 | | return dimy; |
1107 | | } |
1108 | | //! access function |
1109 | | int dimension() const { |
1110 | | return posterior().dimension(); |
1111 | | } |
1112 | | //! access function |
1113 | | const RV& _yrv() const { |
1114 | | return yrv; |
1115 | | } |
1116 | | //! access function |
1117 | | void set_yrv ( const RV &rv ) { |
1118 | | yrv = rv; |
1119 | | } |
1120 | | //! access function |
1121 | | void set_rvc ( const RV &rv ) { |
1122 | | rvc = rv; |
1123 | | } |
1124 | | //! access to rv of the posterior |
1125 | | void set_rv ( const RV &rv ) { |
1126 | | const_cast<epdf&> ( posterior() ).set_rv ( rv ); |
1127 | | } |
1128 | | //! access function |
1129 | | void set_dim ( int dim ) { |
1130 | | const_cast<epdf&> ( posterior() ).set_dim ( dim ); |
1131 | | } |
1132 | | //! return internal log-likelihood of the last data vector |
1133 | | double _ll() const { |
1134 | | return ll; |
1135 | | } |
1136 | | //! switch evaluation of log-likelihood on/off |
1137 | | void set_evalll ( bool evl0 ) { |
1138 | | evalll = evl0; |
1139 | | } |
1140 | | //! return posterior density |
1141 | | virtual const epdf& posterior() const = 0; |
1142 | | //!@} |
1143 | | |
1144 | | //! \name Logging of results |
1145 | | //!@{ |
1146 | | |
1147 | | //! Add all logged variables to a logger |
1148 | | //! Log levels two digits: xy where |
1149 | | //! * y = 0/1 log-likelihood is to be logged |
1150 | | //! * x = level of the posterior (typically 0/1/2 for nothing/mean/bounds) |
1151 | | virtual void log_register ( logger &L, const string &prefix = "" ); |
1152 | | |
1153 | | //! Save results to the given logger, details of what is stored is configured by \c LIDs and \c options |
1154 | | virtual void log_write ( ) const; |
1155 | | |
1156 | | |
1157 | | // TOHLE EFEKTIVNE NAHRAZUJE loglevel |
1158 | | // TODO pozdeji dat private |
1159 | | logged_options logged; |
1160 | | |
1161 | | //!@} |
1162 | | void from_setting ( const Setting &set ) { |
1163 | | shared_ptr<RV> r = UI::build<RV> ( set, "yrv", UI::optional ); |
1164 | | if ( r ) { |
1165 | | set_yrv ( *r ); |
1166 | | } |
1167 | | shared_ptr<RV> r2 = UI::build<RV> ( set, "rvc", UI::optional ); |
1168 | | if ( r2 ) { |
1169 | | rvc = *r2; |
1170 | | } |
1171 | | shared_ptr<RV> r3 = UI::build<RV> ( set, "rv", UI::optional ); |
1172 | | if ( r3 ) { |
1173 | | set_rv ( *r3 ); |
1174 | | } |
1175 | | |
1176 | | UI::get ( logged, set, "logged", UI::optional ); |
1177 | | } |
1178 | | |
1179 | | |
1180 | | void to_setting ( Setting &set ) const { |
1181 | | root::to_setting( set ); |
1182 | | UI::save( &yrv, set, "yrv" ); |
1183 | | UI::save( &rvc, set, "rvc" ); |
1184 | | UI::save( &posterior()._rv(), set, "rv" ); |
1185 | | UI::save( &posterior()._rv(), set, "rv" ); |
1186 | | UI::save( &logged, set, "logged" ); |
1187 | | } |
1188 | | |
1189 | | virtual void set_options ( const string & ); |
1190 | | |
1191 | | // TODO JEN JAKO UKAZKA POUZIT LOGGED[..], NAKONEC ODSTRANIT CELOU METODU, A TAKY JEJI ORIGINAL VYSE |
1192 | | // jen co zavedeme logged_options i do dalsich objektu, pak se vse muze nastavovat primo |
1193 | | // ve from_settingu, bude to tak ok? |
1194 | | // nejlepsi by bylo, kdyby se options posterioru() nastavovaly v jeho from_settingu, |
1195 | | // aby nevznikala takovahle kaskada zavislosti.. pujde to? domyslet |
1196 | | virtual void SHOWING_ROOM( const string & ) |
1197 | | { |
1198 | | if ( logged[full] ) { |
1199 | | const_cast<epdf&> ( posterior() ).set_log_level ( 10 ) ; |
1200 | | } else { |
1201 | | if ( logged[bounds] ) { |
1202 | | const_cast<epdf&> ( posterior() ).set_log_level ( 2 ) ; |
1203 | | } else { |
1204 | | const_cast<epdf&> ( posterior() ).set_log_level ( 1 ) ; |
1205 | | } |
1206 | | if ( logged[likelyhood] ) { |
1207 | | log_level = 1; |
1208 | | } |
1209 | | } |
1210 | | } |
1211 | | |
1212 | | |
1213 | | }; |
1214 | | |
1215 | | //! array of pointers to epdf |
1216 | | typedef Array<shared_ptr<epdf> > epdf_array; |
1217 | | //! array of pointers to pdf |
1218 | | typedef Array<shared_ptr<pdf> > pdf_array; |
1219 | | |
1220 | | template<class EPDF> |
1221 | | vec pdf_internal<EPDF>::samplecond ( const vec &cond ) { |
1222 | | condition ( cond ); |
1223 | | vec temp = iepdf.sample(); |
1224 | | return temp; |
1225 | | } |
1226 | | |
1227 | | template<class EPDF> |
1228 | | mat pdf_internal<EPDF>::samplecond_mat ( const vec &cond, int N ) { |
1229 | | condition ( cond ); |
1230 | | mat temp ( dimension(), N ); |
1231 | | vec smp ( dimension() ); |
1232 | | for ( int i = 0; i < N; i++ ) { |
1233 | | smp = iepdf.sample(); |
1234 | | temp.set_col ( i, smp ); |
1235 | | } |
1236 | | |
1237 | | return temp; |
1238 | | } |
1239 | | |
1240 | | template<class EPDF> |
1241 | | double pdf_internal<EPDF>::evallogcond ( const vec &yt, const vec &cond ) { |
1242 | | double tmp; |
1243 | | condition ( cond ); |
1244 | | tmp = iepdf.evallog ( yt ); |
1245 | | return tmp; |
1246 | | } |
1247 | | |
1248 | | template<class EPDF> |
1249 | | vec pdf_internal<EPDF>::evallogcond_mat ( const mat &Yt, const vec &cond ) { |
1250 | | condition ( cond ); |
1251 | | return iepdf.evallog_mat ( Yt ); |
1252 | | } |
1253 | | |
1254 | | template<class EPDF> |
1255 | | vec pdf_internal<EPDF>::evallogcond_mat ( const Array<vec> &Yt, const vec &cond ) { |
1256 | | condition ( cond ); |
1257 | | return iepdf.evallog_mat ( Yt ); |
1258 | | } |
1259 | | |
1260 | | }; //namespace |
1261 | | #endif // BDMBASE_H |