Changeset 488
- Timestamp:
- 08/08/09 13:43:13 (15 years ago)
- Location:
- library
- Files:
-
- 12 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/base/bdmbase.cpp
r487 r488 140 140 } 141 141 142 template<class EPDF>143 vec mpdf_internal<EPDF>::samplecond ( const vec &cond ) {144 condition ( cond );145 vec temp = iepdf.sample();146 return temp;147 }148 149 template<class EPDF>150 mat mpdf_internal<EPDF>::samplecond_m ( const vec &cond, int N ) {151 condition ( cond );152 mat temp ( dimension(), N );153 vec smp ( dimension() );154 for ( int i = 0; i < N; i++ ) {155 smp = iepdf.sample();156 temp.set_col ( i, smp );157 }158 159 return temp;160 }161 162 template<class EPDF>163 double mpdf_internal<EPDF>::evallogcond ( const vec &dt, const vec &cond ) {164 double tmp;165 condition ( cond );166 tmp = iepdf.evallog ( dt );167 // it_assert_debug(std::isfinite(tmp), "Infinite value");168 return tmp;169 }170 171 template<class EPDF>172 vec mpdf_internal<EPDF>::evallogcond_m ( const mat &Dt, const vec &cond ) {173 condition ( cond );174 return iepdf.evallog_m ( Dt );175 }176 177 template<class EPDF>178 vec mpdf_internal<EPDF>::evallogcond_m ( const Array<vec> &Dt, const vec &cond ) {179 condition ( cond );180 return iepdf.evallog_m ( Dt );181 }182 142 183 143 void mpdf::from_setting ( const Setting &set ) { -
library/bdm/base/bdmbase.h
r487 r488 25 25 using namespace std; 26 26 27 namespace bdm { 27 namespace bdm 28 { 28 29 29 30 typedef std::map<string, int> RVmap; … … 32 33 33 34 //! Structure of RV, i.e. RVs expanded into a flat list of IDs, used for debugging. 34 class str { 35 public: 36 //! vector id ids (non-unique!) 37 ivec ids; 38 //! vector of times 39 ivec times; 40 //!Default constructor 41 str ( ivec ids0, ivec times0 ) : ids ( ids0 ), times ( times0 ) { 42 it_assert_debug ( times0.length() == ids0.length(), "Incompatible input" ); 43 }; 35 class str 36 { 37 public: 38 //! vector id ids (non-unique!) 39 ivec ids; 40 //! vector of times 41 ivec times; 42 //!Default constructor 43 str (ivec ids0, ivec times0) : ids (ids0), times (times0) { 44 it_assert_debug (times0.length() == ids0.length(), "Incompatible input"); 45 }; 44 46 }; 45 47 … … 82 84 */ 83 85 84 class RV : public root { 85 protected: 86 //! size of the data vector 87 int dsize; 88 //! number of individual rvs 89 int len; 90 //! Vector of unique IDs 91 ivec ids; 92 //! Vector of shifts from current time 93 ivec times; 94 95 private: 96 //! auxiliary function used in constructor 97 void init ( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times ); 98 int init ( const string &name, int size ); 99 public: 100 //! \name Constructors 101 //!@{ 102 103 //! Full constructor 104 RV ( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times ) { 105 init ( in_names, in_sizes, in_times ); 106 } 107 108 //! Constructor with times=0 109 RV ( const Array<std::string> &in_names, const ivec &in_sizes ) { 110 init ( in_names, in_sizes, zeros_i ( in_names.length() ) ); 111 } 112 113 //! Constructor with sizes=1, times=0 114 RV ( const Array<std::string> &in_names ) { 115 init ( in_names, ones_i ( in_names.length() ), zeros_i ( in_names.length() ) ); 116 } 117 118 //! Constructor of empty RV 119 RV() : dsize ( 0 ), len ( 0 ), ids ( 0 ), times ( 0 ) {} 120 //! Constructor of a single RV with given id 121 RV ( string name, int sz, int tm = 0 ); 122 //!@} 123 124 //! \name Access functions 125 //!@{ 126 127 //! State output, e.g. for debugging. 128 friend std::ostream &operator<< ( std::ostream &os, const RV &rv ); 129 130 int _dsize() const { 131 return dsize; 132 } 133 134 //! Recount size of the corresponding data vector 135 int countsize() const; 136 ivec cumsizes() const; 137 int length() const { 138 return len; 139 } 140 int id ( int at ) const { 141 return ids ( at ); 142 } 143 int size ( int at ) const { 144 return RV_SIZES ( ids ( at ) ); 145 } 146 int time ( int at ) const { 147 return times ( at ); 148 } 149 std::string name ( int at ) const { 150 return RV_NAMES ( ids ( at ) ); 151 } 152 void set_time ( int at, int time0 ) { 153 times ( at ) = time0; 154 } 155 //!@} 156 157 //TODO why not inline and later?? 158 159 //! \name Algebra on Random Variables 160 //!@{ 161 162 //! Find indices of self in another rv, \return ivec of the same size as self. 163 ivec findself ( const RV &rv2 ) const; 164 //! Compare if \c rv2 is identical to this \c RV 165 bool equal ( const RV &rv2 ) const; 166 //! Add (concat) another variable to the current one, \return true if all rv2 were added, false if rv2 is in conflict 167 bool add ( const RV &rv2 ); 168 //! Subtract another variable from the current one 169 RV subt ( const RV &rv2 ) const; 170 //! Select only variables at indices ind 171 RV subselect ( const ivec &ind ) const; 172 173 //! Select only variables at indices ind 174 RV operator() ( const ivec &ind ) const { 175 return subselect ( ind ); 176 } 177 178 //! Select from data vector starting at di1 to di2 179 RV operator() ( int di1, int di2 ) const; 180 181 //! Shift \c time by delta. 182 void t ( int delta ); 183 //!@} 184 185 //!\name Relation to vectors 186 //!@{ 187 188 //! generate \c str from rv, by expanding sizes TODO to_string.. 189 str tostr() const; 190 //! when this rv is a part of bigger rv, this function returns indices of self in the data vector of the bigger crv. 191 //! Then, data can be copied via: data_of_this = cdata(ind); 192 ivec dataind ( const RV &crv ) const; 193 //! generate mutual indices when copying data between self and crv. 194 //! Data are copied via: data_of_this(selfi) = data_of_rv2(rv2i) 195 void dataind ( const RV &rv2, ivec &selfi, ivec &rv2i ) const; 196 //! Minimum time-offset 197 int mint() const { 198 return min ( times ); 199 } 200 //!@} 201 202 // TODO aktualizovat dle soucasneho UI 203 /*! \brief UI for class RV (description of data vectors) 204 205 \code 206 rv = { 207 type = "rv"; //identifier of the description 208 // UNIQUE IDENTIFIER same names = same variable 209 names = ["a", "b", "c", ...]; // which will be used e.g. in loggers 210 211 //optional arguments 212 sizes = [1, 2, 3, ...]; // (optional) default = ones() 213 times = [-1, -2, 0, ...]; // time shifts with respect to current time (optional) default = zeros() 214 } 215 \endcode 216 */ 217 void from_setting ( const Setting &set ); 218 219 // TODO dodelat void to_setting( Setting &set ) const; 220 221 //! Invalidate all named RVs. Use before initializing any RV instances, with care... 222 static void clear_all(); 223 }; 224 UIREGISTER ( RV ); 86 class RV : public root 87 { 88 protected: 89 //! size of the data vector 90 int dsize; 91 //! number of individual rvs 92 int len; 93 //! Vector of unique IDs 94 ivec ids; 95 //! Vector of shifts from current time 96 ivec times; 97 98 private: 99 //! auxiliary function used in constructor 100 void init (const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times); 101 int init (const string &name, int size); 102 public: 103 //! \name Constructors 104 //!@{ 105 106 //! Full constructor 107 RV (const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times) { 108 init (in_names, in_sizes, in_times); 109 } 110 111 //! Constructor with times=0 112 RV (const Array<std::string> &in_names, const ivec &in_sizes) { 113 init (in_names, in_sizes, zeros_i (in_names.length())); 114 } 115 116 //! Constructor with sizes=1, times=0 117 RV (const Array<std::string> &in_names) { 118 init (in_names, ones_i (in_names.length()), zeros_i (in_names.length())); 119 } 120 121 //! Constructor of empty RV 122 RV() : dsize (0), len (0), ids (0), times (0) {} 123 //! Constructor of a single RV with given id 124 RV (string name, int sz, int tm = 0); 125 //!@} 126 127 //! \name Access functions 128 //!@{ 129 130 //! State output, e.g. for debugging. 131 friend std::ostream &operator<< (std::ostream &os, const RV &rv); 132 133 int _dsize() const { 134 return dsize; 135 } 136 137 //! Recount size of the corresponding data vector 138 int countsize() const; 139 ivec cumsizes() const; 140 int length() const { 141 return len; 142 } 143 int id (int at) const { 144 return ids (at); 145 } 146 int size (int at) const { 147 return RV_SIZES (ids (at)); 148 } 149 int time (int at) const { 150 return times (at); 151 } 152 std::string name (int at) const { 153 return RV_NAMES (ids (at)); 154 } 155 void set_time (int at, int time0) { 156 times (at) = time0; 157 } 158 //!@} 159 160 //TODO why not inline and later?? 161 162 //! \name Algebra on Random Variables 163 //!@{ 164 165 //! Find indices of self in another rv, \return ivec of the same size as self. 166 ivec findself (const RV &rv2) const; 167 //! Compare if \c rv2 is identical to this \c RV 168 bool equal (const RV &rv2) const; 169 //! Add (concat) another variable to the current one, \return true if all rv2 were added, false if rv2 is in conflict 170 bool add (const RV &rv2); 171 //! Subtract another variable from the current one 172 RV subt (const RV &rv2) const; 173 //! Select only variables at indices ind 174 RV subselect (const ivec &ind) const; 175 176 //! Select only variables at indices ind 177 RV operator() (const ivec &ind) const { 178 return subselect (ind); 179 } 180 181 //! Select from data vector starting at di1 to di2 182 RV operator() (int di1, int di2) const; 183 184 //! Shift \c time by delta. 185 void t (int delta); 186 //!@} 187 188 //!\name Relation to vectors 189 //!@{ 190 191 //! generate \c str from rv, by expanding sizes TODO to_string.. 192 str tostr() const; 193 //! when this rv is a part of bigger rv, this function returns indices of self in the data vector of the bigger crv. 194 //! Then, data can be copied via: data_of_this = cdata(ind); 195 ivec dataind (const RV &crv) const; 196 //! generate mutual indices when copying data between self and crv. 197 //! Data are copied via: data_of_this(selfi) = data_of_rv2(rv2i) 198 void dataind (const RV &rv2, ivec &selfi, ivec &rv2i) const; 199 //! Minimum time-offset 200 int mint() const { 201 return min (times); 202 } 203 //!@} 204 205 // TODO aktualizovat dle soucasneho UI 206 /*! \brief UI for class RV (description of data vectors) 207 208 \code 209 rv = { 210 type = "rv"; //identifier of the description 211 // UNIQUE IDENTIFIER same names = same variable 212 names = ["a", "b", "c", ...]; // which will be used e.g. in loggers 213 214 //optional arguments 215 sizes = [1, 2, 3, ...]; // (optional) default = ones() 216 times = [-1, -2, 0, ...]; // time shifts with respect to current time (optional) default = zeros() 217 } 218 \endcode 219 */ 220 void from_setting (const Setting &set); 221 222 // TODO dodelat void to_setting( Setting &set ) const; 223 224 //! Invalidate all named RVs. Use before initializing any RV instances, with care... 225 static void clear_all(); 226 }; 227 UIREGISTER (RV); 225 228 226 229 //! Concat two random variables 227 RV concat ( const RV &rv1, const RV &rv2);230 RV concat (const RV &rv1, const RV &rv2); 228 231 229 232 //!Default empty RV that can be used as default argument … … 232 235 //! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv 233 236 234 class fnc : public root { 235 protected: 236 //! Length of the output vector 237 int dimy; 238 public: 239 //!default constructor 240 fnc() {}; 241 //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond 242 virtual vec eval ( const vec &cond ) { 243 return vec ( 0 ); 244 }; 245 246 //! function substitutes given value into an appropriate position 247 virtual void condition ( const vec &val ) {}; 248 249 //! access function 250 int dimension() const { 251 return dimy; 252 } 237 class fnc : public root 238 { 239 protected: 240 //! Length of the output vector 241 int dimy; 242 public: 243 //!default constructor 244 fnc() {}; 245 //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond 246 virtual vec eval (const vec &cond) { 247 return vec (0); 248 }; 249 250 //! function substitutes given value into an appropriate position 251 virtual void condition (const vec &val) {}; 252 253 //! access function 254 int dimension() const { 255 return dimy; 256 } 253 257 }; 254 258 … … 257 261 //! Probability density function with numerical statistics, e.g. posterior density. 258 262 259 class epdf : public root { 260 protected: 261 //! dimension of the random variable 262 int dim; 263 //! Description of the random variable 264 RV rv; 265 266 public: 267 /*! \name Constructors 268 Construction of each epdf should support two types of constructors: 269 \li empty constructor, 270 \li copy constructor, 271 272 The following constructors should be supported for convenience: 273 \li constructor followed by calling \c set_parameters() 274 \li constructor accepting random variables calling \c set_rv() 275 276 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. 277 @{*/ 278 epdf() : dim ( 0 ), rv() {}; 279 epdf ( const epdf &e ) : dim ( e.dim ), rv ( e.rv ) {}; 280 epdf ( const RV &rv0 ) : dim ( rv0._dsize() ) { 281 set_rv ( rv0 ); 282 }; 283 void set_parameters ( int dim0 ) { 284 dim = dim0; 285 } 286 //!@} 287 288 //! \name Matematical Operations 289 //!@{ 290 291 //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$ 292 virtual vec sample() const { 293 it_error ( "not implemneted" ); 294 return vec ( 0 ); 295 }; 296 //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$ from density \f$ f_x(rv)\f$ 297 virtual mat sample_m ( int N ) const; 298 //! Compute log-probability of argument \c val 299 //! In case the argument is out of suport return -Infinity 300 virtual double evallog ( const vec &val ) const { 301 it_error ( "not implemneted" ); 302 return 0.0; 303 }; 304 //! Compute log-probability of multiple values argument \c val 305 virtual vec evallog_m ( const mat &Val ) const { 306 vec x ( Val.cols() ); 307 for ( int i = 0; i < Val.cols(); i++ ) { 308 x ( i ) = evallog ( Val.get_col ( i ) ) ; 309 } 310 return x; 311 } 312 //! Compute log-probability of multiple values argument \c val 313 virtual vec evallog_m ( const Array<vec> &Avec ) const { 314 vec x ( Avec.size() ); 315 for ( int i = 0; i < Avec.size(); i++ ) { 316 x ( i ) = evallog ( Avec ( i ) ) ; 317 } 318 return x; 319 } 320 //! Return conditional density on the given RV, the remaining rvs will be in conditioning 321 virtual mpdf* condition ( const RV &rv ) const { 322 it_warning ( "Not implemented" ); 323 return NULL; 324 } 325 326 //! Return marginal density on the given RV, the remainig rvs are intergrated out 327 virtual epdf* marginal ( const RV &rv ) const { 328 it_warning ( "Not implemented" ); 329 return NULL; 330 } 331 332 //! return expected value 333 virtual vec mean() const { 334 it_error ( "not implemneted" ); 335 return vec ( 0 ); 336 }; 337 338 //! return expected variance (not covariance!) 339 virtual vec variance() const { 340 it_error ( "not implemneted" ); 341 return vec ( 0 ); 342 }; 343 //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default 344 virtual void qbounds ( vec &lb, vec &ub, double percentage = 0.95 ) const { 345 vec mea = mean(); 346 vec std = sqrt ( variance() ); 347 lb = mea - 2 * std; 348 ub = mea + 2 * std; 349 }; 350 //!@} 351 352 //! \name Connection to other classes 353 //! Description of the random quantity via attribute \c rv is optional. 354 //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization 355 //! and \c conditioning \c rv has to be set. NB: 356 //! @{ 357 358 //!Name its rv 359 void set_rv ( const RV &rv0 ) { 360 rv = rv0; 361 } //it_assert_debug(isnamed(),""); }; 362 //! True if rv is assigned 363 bool isnamed() const { 364 bool b = ( dim == rv._dsize() ); 365 return b; 366 } 367 //! Return name (fails when isnamed is false) 368 const RV& _rv() const { 369 it_assert_debug ( isnamed(), "" ); 370 return rv; 371 } 372 //!@} 373 374 //! \name Access to attributes 375 //! @{ 376 377 //! Size of the random variable 378 int dimension() const { 379 return dim; 380 } 381 //! Load from structure with elements: 382 //! \code 383 //! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable 384 //! // elements of offsprings 385 //! } 386 //! \endcode 387 //!@} 388 void from_setting ( const Setting &set ) { 389 RV* r = UI::build<RV> ( set, "rv" ); 390 if ( r ) { 391 set_rv ( *r ); 392 delete r; 393 } 394 } 263 class epdf : public root 264 { 265 protected: 266 //! dimension of the random variable 267 int dim; 268 //! Description of the random variable 269 RV rv; 270 271 public: 272 /*! \name Constructors 273 Construction of each epdf should support two types of constructors: 274 \li empty constructor, 275 \li copy constructor, 276 277 The following constructors should be supported for convenience: 278 \li constructor followed by calling \c set_parameters() 279 \li constructor accepting random variables calling \c set_rv() 280 281 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. 282 @{*/ 283 epdf() : dim (0), rv() {}; 284 epdf (const epdf &e) : dim (e.dim), rv (e.rv) {}; 285 epdf (const RV &rv0) : dim (rv0._dsize()) { 286 set_rv (rv0); 287 }; 288 void set_parameters (int dim0) { 289 dim = dim0; 290 } 291 //!@} 292 293 //! \name Matematical Operations 294 //!@{ 295 296 //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$ 297 virtual vec sample() const { 298 it_error ("not implemneted"); 299 return vec (0); 300 }; 301 //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$ from density \f$ f_x(rv)\f$ 302 virtual mat sample_m (int N) const; 303 //! Compute log-probability of argument \c val 304 //! In case the argument is out of suport return -Infinity 305 virtual double evallog (const vec &val) const { 306 it_error ("not implemneted"); 307 return 0.0; 308 }; 309 //! Compute log-probability of multiple values argument \c val 310 virtual vec evallog_m (const mat &Val) const { 311 vec x (Val.cols()); 312 for (int i = 0; i < Val.cols(); i++) { 313 x (i) = evallog (Val.get_col (i)) ; 314 } 315 return x; 316 } 317 //! Compute log-probability of multiple values argument \c val 318 virtual vec evallog_m (const Array<vec> &Avec) const { 319 vec x (Avec.size()); 320 for (int i = 0; i < Avec.size(); i++) { 321 x (i) = evallog (Avec (i)) ; 322 } 323 return x; 324 } 325 //! Return conditional density on the given RV, the remaining rvs will be in conditioning 326 virtual mpdf* condition (const RV &rv) const { 327 it_warning ("Not implemented"); 328 return NULL; 329 } 330 331 //! Return marginal density on the given RV, the remainig rvs are intergrated out 332 virtual epdf* marginal (const RV &rv) const { 333 it_warning ("Not implemented"); 334 return NULL; 335 } 336 337 //! return expected value 338 virtual vec mean() const { 339 it_error ("not implemneted"); 340 return vec (0); 341 }; 342 343 //! return expected variance (not covariance!) 344 virtual vec variance() const { 345 it_error ("not implemneted"); 346 return vec (0); 347 }; 348 //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default 349 virtual void qbounds (vec &lb, vec &ub, double percentage = 0.95) const { 350 vec mea = mean(); 351 vec std = sqrt (variance()); 352 lb = mea - 2 * std; 353 ub = mea + 2 * std; 354 }; 355 //!@} 356 357 //! \name Connection to other classes 358 //! Description of the random quantity via attribute \c rv is optional. 359 //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization 360 //! and \c conditioning \c rv has to be set. NB: 361 //! @{ 362 363 //!Name its rv 364 void set_rv (const RV &rv0) { 365 rv = rv0; 366 } //it_assert_debug(isnamed(),""); }; 367 //! True if rv is assigned 368 bool isnamed() const { 369 bool b = (dim == rv._dsize()); 370 return b; 371 } 372 //! Return name (fails when isnamed is false) 373 const RV& _rv() const { 374 it_assert_debug (isnamed(), ""); 375 return rv; 376 } 377 //!@} 378 379 //! \name Access to attributes 380 //! @{ 381 382 //! Size of the random variable 383 int dimension() const { 384 return dim; 385 } 386 //! Load from structure with elements: 387 //! \code 388 //! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable 389 //! // elements of offsprings 390 //! } 391 //! \endcode 392 //!@} 393 void from_setting (const Setting &set) { 394 RV* r = UI::build<RV> (set, "rv"); 395 if (r) { 396 set_rv (*r); 397 delete r; 398 } 399 } 395 400 396 401 }; … … 399 404 //! Conditional probability density, e.g. modeling some dependencies. 400 405 //TODO Samplecond can be generalized 401 class mpdf : public root { 402 protected: 403 //!dimension of the condition 404 int dimc; 405 //! random variable in condition 406 RV rvc; 407 private: 408 //! internal epdf, used only as cache to avoid virtual calls of \c _rv() and \c _dimension() 409 epdf* ep; 410 411 protected: 412 void set_ep(epdf &iepdf) { 413 ep = &iepdf; 414 } 415 416 public: 417 //! \name Constructors 418 //! @{ 419 420 mpdf() : dimc ( 0 ), rvc(), ep(NULL) { } 421 422 mpdf ( const mpdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), ep ( m.ep ) { } 423 //!@} 424 425 //! \name Matematical operations 426 //!@{ 427 428 //! 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 429 virtual vec samplecond ( const vec &cond ){it_error("Not implemented");return vec(0);}; 430 431 //! 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 432 virtual mat samplecond_m ( const vec &cond, int N ){it_error("Not implemented");return mat();} 433 434 435 //! Shortcut for conditioning and evaluation of the internal epdf. In some cases, this operation can be implemented efficiently. 436 virtual double evallogcond ( const vec &dt, const vec &cond ){it_error("Not implemented");return 0.0;} 437 438 //! Matrix version of evallogcond 439 virtual vec evallogcond_m ( const mat &Dt, const vec &cond ){it_error("Not implemented");return vec(0);} 440 441 //! Array<vec> version of evallogcond 442 virtual vec evallogcond_m ( const Array<vec> &Dt, const vec &cond ){it_error("Not implemented");return vec(0);} 443 444 //! \name Access to attributes 445 //! @{ 446 447 RV _rv() { 448 return ep->_rv(); 449 } 450 RV _rvc() { 451 it_assert_debug ( isnamed(), "" ); 452 return rvc; 453 } 454 int dimension() { 455 return ep->dimension(); 456 } 457 int dimensionc() { 458 return dimc; 459 } 460 461 //! Load from structure with elements: 462 //! \code 463 //! { class = "mpdf_offspring", 464 //! rv = {class="RV", names=(...),}; // RV describing meaning of random variable 465 //! rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition 466 //! // elements of offsprings 467 //! } 468 //! \endcode 469 //!@} 470 void from_setting ( const Setting &set ); 471 //!@} 472 473 //! \name Connection to other objects 474 //!@{ 475 void set_rvc ( const RV &rvc0 ) { 476 rvc = rvc0; 477 } 478 void set_rv ( const RV &rv0 ) { 479 ep->set_rv ( rv0 ); 480 } 481 bool isnamed() { 482 return ( ep->isnamed() ) && ( dimc == rvc._dsize() ); 483 } 484 //!@} 406 class mpdf : public root 407 { 408 protected: 409 //!dimension of the condition 410 int dimc; 411 //! random variable in condition 412 RV rvc; 413 private: 414 //! internal epdf, used only as cache to avoid virtual calls of \c _rv() and \c _dimension() 415 epdf* ep; 416 417 protected: 418 void set_ep (epdf &iepdf) { 419 ep = &iepdf; 420 } 421 422 public: 423 //! \name Constructors 424 //! @{ 425 426 mpdf() : dimc (0), rvc(), ep (NULL) { } 427 428 mpdf (const mpdf &m) : dimc (m.dimc), rvc (m.rvc), ep (m.ep) { } 429 //!@} 430 431 //! \name Matematical operations 432 //!@{ 433 434 //! 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 435 virtual vec samplecond (const vec &cond) {it_error ("Not implemented");return vec (0);}; 436 437 //! 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 438 virtual mat samplecond_m (const vec &cond, int N) {it_error ("Not implemented");return mat();} 439 440 441 //! Shortcut for conditioning and evaluation of the internal epdf. In some cases, this operation can be implemented efficiently. 442 virtual double evallogcond (const vec &dt, const vec &cond) {it_error ("Not implemented");return 0.0;} 443 444 //! Matrix version of evallogcond 445 virtual vec evallogcond_m (const mat &Dt, const vec &cond) {it_error ("Not implemented");return vec (0);} 446 447 //! Array<vec> version of evallogcond 448 virtual vec evallogcond_m (const Array<vec> &Dt, const vec &cond) {it_error ("Not implemented");return vec (0);} 449 450 //! \name Access to attributes 451 //! @{ 452 453 RV _rv() { 454 return ep->_rv(); 455 } 456 RV _rvc() { 457 it_assert_debug (isnamed(), ""); 458 return rvc; 459 } 460 int dimension() { 461 return ep->dimension(); 462 } 463 int dimensionc() { 464 return dimc; 465 } 466 467 //! Load from structure with elements: 468 //! \code 469 //! { class = "mpdf_offspring", 470 //! rv = {class="RV", names=(...),}; // RV describing meaning of random variable 471 //! rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition 472 //! // elements of offsprings 473 //! } 474 //! \endcode 475 //!@} 476 void from_setting (const Setting &set); 477 //!@} 478 479 //! \name Connection to other objects 480 //!@{ 481 void set_rvc (const RV &rvc0) { 482 rvc = rvc0; 483 } 484 void set_rv (const RV &rv0) { 485 ep->set_rv (rv0); 486 } 487 bool isnamed() { 488 return (ep->isnamed()) && (dimc == rvc._dsize()); 489 } 490 //!@} 485 491 }; 486 492 487 493 template <class EPDF> 488 class mpdf_internal: public mpdf{ 494 class mpdf_internal: public mpdf 495 { 489 496 protected : 490 497 EPDF iepdf; 491 498 public: 492 499 //! constructor 493 mpdf_internal() : mpdf(),iepdf(){set_ep(iepdf);}500 mpdf_internal() : mpdf(), iepdf() {set_ep (iepdf);} 494 501 //! Update \c iepdf so that it represents this mpdf conditioned on \c rvc = cond 495 502 //! This function provides convenient reimplementation in offsprings 496 virtual void condition ( const vec &cond) {497 it_error ( "Not implemented");498 503 virtual void condition (const vec &cond) { 504 it_error ("Not implemented"); 505 }; 499 506 //!access function to iepdf 500 EPDF& e() {return iepdf;}501 507 EPDF& e() {return iepdf;} 508 502 509 //! Reimplements samplecond using \c condition() 503 vec samplecond ( const vec &cond);510 vec samplecond (const vec &cond); 504 511 //! Reimplements evallogcond using \c condition() 505 double evallogcond ( const vec &val, const vec &cond);506 //! Efficient version of evallogcond for matrices 507 virtual vec evallogcond_m ( const mat &Dt, const vec &cond);512 double evallogcond (const vec &val, const vec &cond); 513 //! Efficient version of evallogcond for matrices 514 virtual vec evallogcond_m (const mat &Dt, const vec &cond); 508 515 //! Efficient version of evallogcond for Array<vec> 509 virtual vec evallogcond_m ( const Array<vec> &Dt, const vec &cond);510 //! Efficient version of samplecond 511 virtual mat samplecond_m ( const vec &cond, int N);516 virtual vec evallogcond_m (const Array<vec> &Dt, const vec &cond); 517 //! Efficient version of samplecond 518 virtual mat samplecond_m (const vec &cond, int N); 512 519 }; 513 520 … … 537 544 538 545 */ 539 class datalink { 540 protected: 541 //! Remember how long val should be 542 int downsize; 543 544 //! Remember how long val of "Up" should be 545 int upsize; 546 547 //! val-to-val link, indices of the upper val 548 ivec v2v_up; 549 550 public: 551 //! Constructor 552 datalink() : downsize ( 0 ), upsize ( 0 ) { } 553 datalink ( const RV &rv, const RV &rv_up ) { 554 set_connection ( rv, rv_up ); 555 } 556 557 //! set connection, rv must be fully present in rv_up 558 void set_connection ( const RV &rv, const RV &rv_up ) { 559 downsize = rv._dsize(); 560 upsize = rv_up._dsize(); 561 v2v_up = rv.dataind ( rv_up ); 562 563 it_assert_debug ( v2v_up.length() == downsize, "rv is not fully in rv_up" ); 564 } 565 566 //! set connection using indices 567 void set_connection ( int ds, int us, const ivec &upind ) { 568 downsize = ds; 569 upsize = us; 570 v2v_up = upind; 571 572 it_assert_debug ( v2v_up.length() == downsize, "rv is not fully in rv_up" ); 573 } 574 575 //! Get val for myself from val of "Up" 576 vec pushdown ( const vec &val_up ) { 577 it_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); 578 return get_vec ( val_up, v2v_up ); 579 } 580 581 //! Fill val of "Up" by my pieces 582 void pushup ( vec &val_up, const vec &val ) { 583 it_assert_debug ( downsize == val.length(), "Wrong val" ); 584 it_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); 585 set_subvector ( val_up, v2v_up, val ); 586 } 546 class datalink 547 { 548 protected: 549 //! Remember how long val should be 550 int downsize; 551 552 //! Remember how long val of "Up" should be 553 int upsize; 554 555 //! val-to-val link, indices of the upper val 556 ivec v2v_up; 557 558 public: 559 //! Constructor 560 datalink() : downsize (0), upsize (0) { } 561 datalink (const RV &rv, const RV &rv_up) { 562 set_connection (rv, rv_up); 563 } 564 565 //! set connection, rv must be fully present in rv_up 566 void set_connection (const RV &rv, const RV &rv_up) { 567 downsize = rv._dsize(); 568 upsize = rv_up._dsize(); 569 v2v_up = rv.dataind (rv_up); 570 571 it_assert_debug (v2v_up.length() == downsize, "rv is not fully in rv_up"); 572 } 573 574 //! set connection using indices 575 void set_connection (int ds, int us, const ivec &upind) { 576 downsize = ds; 577 upsize = us; 578 v2v_up = upind; 579 580 it_assert_debug (v2v_up.length() == downsize, "rv is not fully in rv_up"); 581 } 582 583 //! Get val for myself from val of "Up" 584 vec pushdown (const vec &val_up) { 585 it_assert_debug (upsize == val_up.length(), "Wrong val_up"); 586 return get_vec (val_up, v2v_up); 587 } 588 589 //! Fill val of "Up" by my pieces 590 void pushup (vec &val_up, const vec &val) { 591 it_assert_debug (downsize == val.length(), "Wrong val"); 592 it_assert_debug (upsize == val_up.length(), "Wrong val_up"); 593 set_subvector (val_up, v2v_up, val); 594 } 587 595 }; 588 596 589 597 //! Data link with a condition. 590 class datalink_m2e: public datalink { 591 protected: 592 //! Remember how long cond should be 593 int condsize; 594 595 //!upper_val-to-local_cond link, indices of the upper val 596 ivec v2c_up; 597 598 //!upper_val-to-local_cond link, indices of the local cond 599 ivec v2c_lo; 600 601 public: 602 //! Constructor 603 datalink_m2e() : condsize ( 0 ) { } 604 605 void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up ) { 606 datalink::set_connection ( rv, rv_up ); 607 condsize = rvc._dsize(); 608 //establish v2c connection 609 rvc.dataind ( rv_up, v2c_lo, v2c_up ); 610 } 611 612 //!Construct condition 613 vec get_cond ( const vec &val_up ) { 614 vec tmp ( condsize ); 615 set_subvector ( tmp, v2c_lo, val_up ( v2c_up ) ); 616 return tmp; 617 } 618 619 void pushup_cond ( vec &val_up, const vec &val, const vec &cond ) { 620 it_assert_debug ( downsize == val.length(), "Wrong val" ); 621 it_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); 622 set_subvector ( val_up, v2v_up, val ); 623 set_subvector ( val_up, v2c_up, cond ); 624 } 598 class datalink_m2e: public datalink 599 { 600 protected: 601 //! Remember how long cond should be 602 int condsize; 603 604 //!upper_val-to-local_cond link, indices of the upper val 605 ivec v2c_up; 606 607 //!upper_val-to-local_cond link, indices of the local cond 608 ivec v2c_lo; 609 610 public: 611 //! Constructor 612 datalink_m2e() : condsize (0) { } 613 614 void set_connection (const RV &rv, const RV &rvc, const RV &rv_up) { 615 datalink::set_connection (rv, rv_up); 616 condsize = rvc._dsize(); 617 //establish v2c connection 618 rvc.dataind (rv_up, v2c_lo, v2c_up); 619 } 620 621 //!Construct condition 622 vec get_cond (const vec &val_up) { 623 vec tmp (condsize); 624 set_subvector (tmp, v2c_lo, val_up (v2c_up)); 625 return tmp; 626 } 627 628 void pushup_cond (vec &val_up, const vec &val, const vec &cond) { 629 it_assert_debug (downsize == val.length(), "Wrong val"); 630 it_assert_debug (upsize == val_up.length(), "Wrong val_up"); 631 set_subvector (val_up, v2v_up, val); 632 set_subvector (val_up, v2c_up, cond); 633 } 625 634 }; 626 635 627 636 //!DataLink is a connection between mpdf and its superordinate (Up) 628 637 //! This class links 629 class datalink_m2m: public datalink_m2e { 630 protected: 631 //!cond-to-cond link, indices of the upper cond 632 ivec c2c_up; 633 //!cond-to-cond link, indices of the local cond 634 ivec c2c_lo; 635 636 public: 637 //! Constructor 638 datalink_m2m() {}; 639 void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) { 640 datalink_m2e::set_connection ( rv, rvc, rv_up ); 641 //establish c2c connection 642 rvc.dataind ( rvc_up, c2c_lo, c2c_up ); 643 it_assert_debug ( c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given" ); 644 } 645 646 //! Get cond for myself from val and cond of "Up" 647 vec get_cond ( const vec &val_up, const vec &cond_up ) { 648 vec tmp ( condsize ); 649 set_subvector ( tmp, v2c_lo, val_up ( v2c_up ) ); 650 set_subvector ( tmp, c2c_lo, cond_up ( c2c_up ) ); 651 return tmp; 652 } 653 //! Fill 638 class datalink_m2m: public datalink_m2e 639 { 640 protected: 641 //!cond-to-cond link, indices of the upper cond 642 ivec c2c_up; 643 //!cond-to-cond link, indices of the local cond 644 ivec c2c_lo; 645 646 public: 647 //! Constructor 648 datalink_m2m() {}; 649 void set_connection (const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up) { 650 datalink_m2e::set_connection (rv, rvc, rv_up); 651 //establish c2c connection 652 rvc.dataind (rvc_up, c2c_lo, c2c_up); 653 it_assert_debug (c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given"); 654 } 655 656 //! Get cond for myself from val and cond of "Up" 657 vec get_cond (const vec &val_up, const vec &cond_up) { 658 vec tmp (condsize); 659 set_subvector (tmp, v2c_lo, val_up (v2c_up)); 660 set_subvector (tmp, c2c_lo, cond_up (c2c_up)); 661 return tmp; 662 } 663 //! Fill 654 664 655 665 }; … … 660 670 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. 661 671 */ 662 class logger : public root { 663 protected: 664 //! RVs of all logged variables. 665 Array<RV> entries; 666 //! Names of logged quantities, e.g. names of algorithm variants 667 Array<string> names; 668 public: 669 //!Default constructor 670 logger() : entries ( 0 ), names ( 0 ) {} 671 672 //! returns an identifier which will be later needed for calling the \c logit() function 673 //! For empty RV it returns -1, this entry will be ignored by \c logit(). 674 virtual int add ( const RV &rv, string prefix = "" ) { 675 int id; 676 if ( rv._dsize() > 0 ) { 677 id = entries.length(); 678 names = concat ( names, prefix ); // diff 679 entries.set_length ( id + 1, true ); 680 entries ( id ) = rv; 681 } else { 682 id = -1; 683 } 684 return id; // identifier of the last entry 685 } 686 687 //! log this vector 688 virtual void logit ( int id, const vec &v ) = 0; 689 //! log this double 690 virtual void logit ( int id, const double &d ) = 0; 691 692 //! Shifts storage position for another time step. 693 virtual void step() = 0; 694 695 //! Finalize storing information 696 virtual void finalize() {}; 697 698 //! Initialize the storage 699 virtual void init() {}; 672 class logger : public root 673 { 674 protected: 675 //! RVs of all logged variables. 676 Array<RV> entries; 677 //! Names of logged quantities, e.g. names of algorithm variants 678 Array<string> names; 679 public: 680 //!Default constructor 681 logger() : entries (0), names (0) {} 682 683 //! returns an identifier which will be later needed for calling the \c logit() function 684 //! For empty RV it returns -1, this entry will be ignored by \c logit(). 685 virtual int add (const RV &rv, string prefix = "") { 686 int id; 687 if (rv._dsize() > 0) { 688 id = entries.length(); 689 names = concat (names, prefix); // diff 690 entries.set_length (id + 1, true); 691 entries (id) = rv; 692 } else { 693 id = -1; 694 } 695 return id; // identifier of the last entry 696 } 697 698 //! log this vector 699 virtual void logit (int id, const vec &v) = 0; 700 //! log this double 701 virtual void logit (int id, const double &d) = 0; 702 703 //! Shifts storage position for another time step. 704 virtual void step() = 0; 705 706 //! Finalize storing information 707 virtual void finalize() {}; 708 709 //! Initialize the storage 710 virtual void init() {}; 700 711 701 712 }; … … 704 715 705 716 */ 706 class mepdf : public mpdf { 707 708 shared_ptr<epdf> ipdf; 709 public: 710 //!Default constructor 711 mepdf() { } 712 713 mepdf ( shared_ptr<epdf> em ) { 714 ipdf = em; 715 set_ep(*ipdf.get()); 716 dimc = 0; 717 } 718 719 //! empty 720 void condition ( const vec &cond ); 721 722 //! Load from structure with elements: 723 //! \code 724 //! { class = "mepdf", 725 //! epdf = {class="epdf_offspring",...} 726 //! } 727 //! \endcode 728 //!@} 729 void from_setting ( const Setting &set ); 730 }; 731 UIREGISTER ( mepdf ); 717 class mepdf : public mpdf 718 { 719 720 shared_ptr<epdf> ipdf; 721 public: 722 //!Default constructor 723 mepdf() { } 724 725 mepdf (shared_ptr<epdf> em) { 726 ipdf = em; 727 set_ep (*ipdf.get()); 728 dimc = 0; 729 } 730 731 //! empty 732 void condition (const vec &cond); 733 734 //! Load from structure with elements: 735 //! \code 736 //! { class = "mepdf", 737 //! epdf = {class="epdf_offspring",...} 738 //! } 739 //! \endcode 740 //!@} 741 void from_setting (const Setting &set); 742 }; 743 UIREGISTER (mepdf); 732 744 733 745 //!\brief Chain rule of pdfs - abstract part common for mprod and merger. 734 746 //!this abstract class is common to epdf and mpdf 735 747 //!\todo Think of better design - global functions rv=get_rv(Array<mpdf*> mpdfs); ?? 736 class compositepdf { 737 protected: 738 //! Elements of composition 739 Array<mpdf*> mpdfs; 740 bool owning_mpdfs; 741 public: 742 compositepdf() : mpdfs ( 0 ) {}; 743 compositepdf ( Array<mpdf*> A0, bool own = false ) { 744 set_elements ( A0, own ); 745 }; 746 void set_elements ( Array<mpdf*> A0, bool own = false ) { 747 mpdfs = A0; 748 owning_mpdfs = own; 749 }; 750 //! find common rv, flag \param checkoverlap modifies whether overlaps are acceptable 751 RV getrv ( bool checkoverlap = false ); 752 //! common rvc of all mpdfs is written to rvc 753 void setrvc ( const RV &rv, RV &rvc ); 754 ~compositepdf() { 755 if ( owning_mpdfs ) for ( int i = 0; i < mpdfs.length(); i++ ) { 756 delete mpdfs ( i ); 757 } 758 }; 748 class compositepdf 749 { 750 protected: 751 //! Elements of composition 752 Array<mpdf*> mpdfs; 753 bool owning_mpdfs; 754 public: 755 compositepdf() : mpdfs (0) {}; 756 compositepdf (Array<mpdf*> A0, bool own = false) { 757 set_elements (A0, own); 758 }; 759 void set_elements (Array<mpdf*> A0, bool own = false) { 760 mpdfs = A0; 761 owning_mpdfs = own; 762 }; 763 //! find common rv, flag \param checkoverlap modifies whether overlaps are acceptable 764 RV getrv (bool checkoverlap = false); 765 //! common rvc of all mpdfs is written to rvc 766 void setrvc (const RV &rv, RV &rvc); 767 ~compositepdf() { 768 if (owning_mpdfs) for (int i = 0; i < mpdfs.length(); i++) { 769 delete mpdfs (i); 770 } 771 }; 759 772 }; 760 773 … … 766 779 */ 767 780 768 class DS : public root { 769 protected: 770 int dtsize; 771 int utsize; 772 //!Description of data returned by \c getdata(). 773 RV Drv; 774 //!Description of data witten by by \c write(). 775 RV Urv; // 776 //! Remember its own index in Logger L 777 int L_dt, L_ut; 778 public: 779 //! default constructors 780 DS() : Drv(), Urv() {}; 781 //! Returns full vector of observed data=[output, input] 782 virtual void getdata ( vec &dt ) { 783 it_error ( "abstract class" ); 784 }; 785 //! Returns data records at indeces. 786 virtual void getdata ( vec &dt, const ivec &indeces ) { 787 it_error ( "abstract class" ); 788 }; 789 //! Accepts action variable and schedule it for application. 790 virtual void write ( vec &ut ) { 791 it_error ( "abstract class" ); 792 }; 793 //! Accepts action variables at specific indeces 794 virtual void write ( vec &ut, const ivec &indeces ) { 795 it_error ( "abstract class" ); 796 }; 797 798 //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system. 799 virtual void step() = 0; 800 801 //! Register DS for logging into logger L 802 virtual void log_add ( logger &L ) { 803 it_assert_debug ( dtsize == Drv._dsize(), "" ); 804 it_assert_debug ( utsize == Urv._dsize(), "" ); 805 806 L_dt = L.add ( Drv, "" ); 807 L_ut = L.add ( Urv, "" ); 808 } 809 //! Register DS for logging into logger L 810 virtual void logit ( logger &L ) { 811 vec tmp ( Drv._dsize() + Urv._dsize() ); 812 getdata ( tmp ); 813 // d is first in getdata 814 L.logit ( L_dt, tmp.left ( Drv._dsize() ) ); 815 // u follows after d in getdata 816 L.logit ( L_ut, tmp.mid ( Drv._dsize(), Urv._dsize() ) ); 817 } 818 //!access function 819 virtual RV _drv() const { 820 return concat ( Drv, Urv ); 821 } 822 //!access function 823 const RV& _urv() const { 824 return Urv; 825 } 826 //! set random rvariables 827 virtual void set_drv ( const RV &drv, const RV &urv ) { 828 Drv = drv; 829 Urv = urv; 830 } 781 class DS : public root 782 { 783 protected: 784 int dtsize; 785 int utsize; 786 //!Description of data returned by \c getdata(). 787 RV Drv; 788 //!Description of data witten by by \c write(). 789 RV Urv; // 790 //! Remember its own index in Logger L 791 int L_dt, L_ut; 792 public: 793 //! default constructors 794 DS() : Drv(), Urv() {}; 795 //! Returns full vector of observed data=[output, input] 796 virtual void getdata (vec &dt) { 797 it_error ("abstract class"); 798 }; 799 //! Returns data records at indeces. 800 virtual void getdata (vec &dt, const ivec &indeces) { 801 it_error ("abstract class"); 802 }; 803 //! Accepts action variable and schedule it for application. 804 virtual void write (vec &ut) { 805 it_error ("abstract class"); 806 }; 807 //! Accepts action variables at specific indeces 808 virtual void write (vec &ut, const ivec &indeces) { 809 it_error ("abstract class"); 810 }; 811 812 //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system. 813 virtual void step() = 0; 814 815 //! Register DS for logging into logger L 816 virtual void log_add (logger &L) { 817 it_assert_debug (dtsize == Drv._dsize(), ""); 818 it_assert_debug (utsize == Urv._dsize(), ""); 819 820 L_dt = L.add (Drv, ""); 821 L_ut = L.add (Urv, ""); 822 } 823 //! Register DS for logging into logger L 824 virtual void logit (logger &L) { 825 vec tmp (Drv._dsize() + Urv._dsize()); 826 getdata (tmp); 827 // d is first in getdata 828 L.logit (L_dt, tmp.left (Drv._dsize())); 829 // u follows after d in getdata 830 L.logit (L_ut, tmp.mid (Drv._dsize(), Urv._dsize())); 831 } 832 //!access function 833 virtual RV _drv() const { 834 return concat (Drv, Urv); 835 } 836 //!access function 837 const RV& _urv() const { 838 return Urv; 839 } 840 //! set random rvariables 841 virtual void set_drv (const RV &drv, const RV &urv) { 842 Drv = drv; 843 Urv = urv; 844 } 831 845 }; 832 846 … … 852 866 */ 853 867 854 class BM : public root { 855 protected: 856 //! Random variable of the data (optional) 857 RV drv; 858 //!Logarithm of marginalized data likelihood. 859 double ll; 860 //! 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. 861 bool evalll; 862 public: 863 //! \name Constructors 864 //! @{ 865 866 BM() : ll ( 0 ), evalll ( true ), LIDs ( 4 ), LFlags ( 4 ) { 867 LIDs = -1;/*empty IDs*/ 868 LFlags = 0; 869 LFlags ( 0 ) = 1;/*log only mean*/ 870 }; 871 BM ( const BM &B ) : drv ( B.drv ), ll ( B.ll ), evalll ( B.evalll ) {} 872 //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually! 873 //! Prototype: \code BM* _copy_() const {return new BM(*this);} \endcode 874 virtual BM* _copy_() const { 875 return NULL; 876 }; 877 //!@} 878 879 //! \name Mathematical operations 880 //!@{ 881 882 /*! \brief Incremental Bayes rule 883 @param dt vector of input data 884 */ 885 virtual void bayes ( const vec &dt ) = 0; 886 //! Batch Bayes rule (columns of Dt are observations) 887 virtual void bayesB ( const mat &Dt ); 888 //! Evaluates predictive log-likelihood of the given data record 889 //! I.e. marginal likelihood of the data with the posterior integrated out. 890 virtual double logpred ( const vec &dt ) const { 891 it_error ( "Not implemented" ); 892 return 0.0; 868 class BM : public root 869 { 870 protected: 871 //! Random variable of the data (optional) 872 RV drv; 873 //!Logarithm of marginalized data likelihood. 874 double ll; 875 //! 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. 876 bool evalll; 877 public: 878 //! \name Constructors 879 //! @{ 880 881 BM() : ll (0), evalll (true), LIDs (4), LFlags (4) { 882 LIDs = -1;/*empty IDs*/ 883 LFlags = 0; 884 LFlags (0) = 1; /*log only mean*/ 885 }; 886 BM (const BM &B) : drv (B.drv), ll (B.ll), evalll (B.evalll) {} 887 //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually! 888 //! Prototype: \code BM* _copy_() const {return new BM(*this);} \endcode 889 virtual BM* _copy_() const { 890 return NULL; 891 }; 892 //!@} 893 894 //! \name Mathematical operations 895 //!@{ 896 897 /*! \brief Incremental Bayes rule 898 @param dt vector of input data 899 */ 900 virtual void bayes (const vec &dt) = 0; 901 //! Batch Bayes rule (columns of Dt are observations) 902 virtual void bayesB (const mat &Dt); 903 //! Evaluates predictive log-likelihood of the given data record 904 //! I.e. marginal likelihood of the data with the posterior integrated out. 905 virtual double logpred (const vec &dt) const { 906 it_error ("Not implemented"); 907 return 0.0; 908 } 909 //! Matrix version of logpred 910 vec logpred_m (const mat &dt) const { 911 vec tmp (dt.cols()); 912 for (int i = 0; i < dt.cols(); i++) { 913 tmp (i) = logpred (dt.get_col (i)); 914 } 915 return tmp; 916 } 917 918 //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$ 919 virtual epdf* epredictor() const { 920 it_error ("Not implemented"); 921 return NULL; 922 }; 923 //!Constructs a conditional density 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) 924 virtual mpdf* predictor() const { 925 it_error ("Not implemented"); 926 return NULL; 927 }; 928 //!@} 929 930 //! \name Extension to conditional BM 931 //! This extension is useful e.g. in Marginalized Particle Filter (\ref bdm::MPF). 932 //! Alternatively, it can be used for automated connection to DS when the condition is observed 933 //!@{ 934 935 //! Name of extension variable 936 RV rvc; 937 //! access function 938 const RV& _rvc() const { 939 return rvc; 940 } 941 942 //! Substitute \c val for \c rvc. 943 virtual void condition (const vec &val) { 944 it_error ("Not implemented!"); 945 }; 946 947 //!@} 948 949 950 //! \name Access to attributes 951 //!@{ 952 953 const RV& _drv() const { 954 return drv; 955 } 956 void set_drv (const RV &rv) { 957 drv = rv; 958 } 959 void set_rv (const RV &rv) { 960 const_cast<epdf&> (posterior()).set_rv (rv); 961 } 962 double _ll() const { 963 return ll; 964 } 965 void set_evalll (bool evl0) { 966 evalll = evl0; 967 } 968 virtual const epdf& posterior() const = 0; 969 virtual const epdf* _e() const = 0; 970 //!@} 971 972 //! \name Logging of results 973 //!@{ 974 975 //! Set boolean options from a string, recognized are: "logbounds,logll" 976 virtual void set_options (const string &opt) { 977 LFlags (0) = 1; 978 if (opt.find ("logbounds") != string::npos) { 979 LFlags (1) = 1; 980 LFlags (2) = 1; 981 } 982 if (opt.find ("logll") != string::npos) { 983 LFlags (3) = 1; 984 } 985 } 986 //! IDs of storages in loggers 4:[1=mean,2=lb,3=ub,4=ll] 987 ivec LIDs; 988 989 //! Flags for logging - same size as LIDs, each entry correspond to the same in LIDs 990 ivec LFlags; 991 //! Add all logged variables to a logger 992 virtual void log_add (logger &L, const string &name = "") { 993 // internal 994 RV r; 995 if (posterior().isnamed()) { 996 r = posterior()._rv(); 997 } else { 998 r = RV ("est", posterior().dimension()); 999 }; 1000 1001 // Add mean value 1002 if (LFlags (0)) LIDs (0) = L.add (r, name + "mean_"); 1003 if (LFlags (1)) LIDs (1) = L.add (r, name + "lb_"); 1004 if (LFlags (2)) LIDs (2) = L.add (r, name + "ub_"); 1005 if (LFlags (3)) LIDs (3) = L.add (RV ("ll", 1), name); //TODO: "local" RV 1006 } 1007 virtual void logit (logger &L) { 1008 L.logit (LIDs (0), posterior().mean()); 1009 if (LFlags (1) || LFlags (2)) { //if one of them is off, its LID==-1 and will not be stored 1010 vec ub, lb; 1011 posterior().qbounds (lb, ub); 1012 L.logit (LIDs (1), lb); 1013 L.logit (LIDs (2), ub); 1014 } 1015 if (LFlags (3)) L.logit (LIDs (3), ll); 1016 } 1017 //!@} 1018 }; 1019 1020 template<class EPDF> 1021 vec mpdf_internal<EPDF>::samplecond (const vec &cond) 1022 { 1023 condition (cond); 1024 vec temp = iepdf.sample(); 1025 return temp; 1026 } 1027 1028 template<class EPDF> 1029 mat mpdf_internal<EPDF>::samplecond_m (const vec &cond, int N) 1030 { 1031 condition (cond); 1032 mat temp (dimension(), N); 1033 vec smp (dimension()); 1034 for (int i = 0; i < N; i++) { 1035 smp = iepdf.sample(); 1036 temp.set_col (i, smp); 893 1037 } 894 //! Matrix version of logpred 895 vec logpred_m ( const mat &dt ) const { 896 vec tmp ( dt.cols() ); 897 for ( int i = 0; i < dt.cols(); i++ ) { 898 tmp ( i ) = logpred ( dt.get_col ( i ) ); 899 } 900 return tmp; 901 } 902 903 //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$ 904 virtual epdf* epredictor() const { 905 it_error ( "Not implemented" ); 906 return NULL; 907 }; 908 //!Constructs a conditional density 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) 909 virtual mpdf* predictor() const { 910 it_error ( "Not implemented" ); 911 return NULL; 912 }; 913 //!@} 914 915 //! \name Extension to conditional BM 916 //! This extension is useful e.g. in Marginalized Particle Filter (\ref bdm::MPF). 917 //! Alternatively, it can be used for automated connection to DS when the condition is observed 918 //!@{ 919 920 //! Name of extension variable 921 RV rvc; 922 //! access function 923 const RV& _rvc() const { 924 return rvc; 925 } 926 927 //! Substitute \c val for \c rvc. 928 virtual void condition ( const vec &val ) { 929 it_error ( "Not implemented!" ); 930 }; 931 932 //!@} 933 934 935 //! \name Access to attributes 936 //!@{ 937 938 const RV& _drv() const { 939 return drv; 940 } 941 void set_drv ( const RV &rv ) { 942 drv = rv; 943 } 944 void set_rv ( const RV &rv ) { 945 const_cast<epdf&> ( posterior() ).set_rv ( rv ); 946 } 947 double _ll() const { 948 return ll; 949 } 950 void set_evalll ( bool evl0 ) { 951 evalll = evl0; 952 } 953 virtual const epdf& posterior() const = 0; 954 virtual const epdf* _e() const = 0; 955 //!@} 956 957 //! \name Logging of results 958 //!@{ 959 960 //! Set boolean options from a string, recognized are: "logbounds,logll" 961 virtual void set_options ( const string &opt ) { 962 LFlags ( 0 ) = 1; 963 if ( opt.find ( "logbounds" ) != string::npos ) { 964 LFlags ( 1 ) = 1; 965 LFlags ( 2 ) = 1; 966 } 967 if ( opt.find ( "logll" ) != string::npos ) { 968 LFlags ( 3 ) = 1; 969 } 970 } 971 //! IDs of storages in loggers 4:[1=mean,2=lb,3=ub,4=ll] 972 ivec LIDs; 973 974 //! Flags for logging - same size as LIDs, each entry correspond to the same in LIDs 975 ivec LFlags; 976 //! Add all logged variables to a logger 977 virtual void log_add ( logger &L, const string &name = "" ) { 978 // internal 979 RV r; 980 if ( posterior().isnamed() ) { 981 r = posterior()._rv(); 982 } else { 983 r = RV ( "est", posterior().dimension() ); 984 }; 985 986 // Add mean value 987 if ( LFlags ( 0 ) ) LIDs ( 0 ) = L.add ( r, name + "mean_" ); 988 if ( LFlags ( 1 ) ) LIDs ( 1 ) = L.add ( r, name + "lb_" ); 989 if ( LFlags ( 2 ) ) LIDs ( 2 ) = L.add ( r, name + "ub_" ); 990 if ( LFlags ( 3 ) ) LIDs ( 3 ) = L.add ( RV ( "ll", 1 ), name ); //TODO: "local" RV 991 } 992 virtual void logit ( logger &L ) { 993 L.logit ( LIDs ( 0 ), posterior().mean() ); 994 if ( LFlags ( 1 ) || LFlags ( 2 ) ) { //if one of them is off, its LID==-1 and will not be stored 995 vec ub, lb; 996 posterior().qbounds ( lb, ub ); 997 L.logit ( LIDs ( 1 ), lb ); 998 L.logit ( LIDs ( 2 ), ub ); 999 } 1000 if ( LFlags ( 3 ) ) L.logit ( LIDs ( 3 ), ll ); 1001 } 1002 //!@} 1003 }; 1004 1038 1039 return temp; 1040 } 1041 1042 template<class EPDF> 1043 double mpdf_internal<EPDF>::evallogcond (const vec &dt, const vec &cond) 1044 { 1045 double tmp; 1046 condition (cond); 1047 tmp = iepdf.evallog (dt); 1048 // it_assert_debug(std::isfinite(tmp), "Infinite value"); 1049 return tmp; 1050 } 1051 1052 template<class EPDF> 1053 vec mpdf_internal<EPDF>::evallogcond_m (const mat &Dt, const vec &cond) 1054 { 1055 condition (cond); 1056 return iepdf.evallog_m (Dt); 1057 } 1058 1059 template<class EPDF> 1060 vec mpdf_internal<EPDF>::evallogcond_m (const Array<vec> &Dt, const vec &cond) 1061 { 1062 condition (cond); 1063 return iepdf.evallog_m (Dt); 1064 } 1005 1065 1006 1066 }; //namespace -
library/bdm/estim/particles.h
r487 r488 67 67 resmethod = rm; 68 68 }; 69 void set_statistics ( const vec w0, epdf *epdf0 ) {69 void set_statistics ( const vec w0, const epdf &epdf0 ) { 70 70 est.set_statistics ( w0, epdf0 ); 71 71 }; … … 201 201 BMs.set_length ( n0 ); 202 202 } 203 void set_statistics ( epdf *epdf0, const BM_T* BMcond0 ) {203 void set_statistics ( const epdf &epdf0, const BM_T* BMcond0 ) { 204 204 205 205 PF::set_statistics ( ones ( n ) / n, epdf0 ); -
library/bdm/stat/emix.cpp
r477 r488 199 199 return aprgiw; 200 200 }; 201 202 vec mmix::samplecond(const vec &cond) { 203 //Sample which component 204 vec cumDist = cumsum ( w ); 205 double u0; 206 #pragma omp critical 207 u0 = UniRNG.sample(); 208 209 int i = 0; 210 while ( ( cumDist ( i ) < u0 ) && ( i < ( w.length() - 1 ) ) ) { 211 i++; 212 } 213 214 return Coms ( i )->samplecond(cond); 215 } 201 216 202 217 } -
library/bdm/stat/emix.h
r487 r488 472 472 473 473 474 /*! \brief Mixture of mpdfs with constant weights, all mpdfs are of equal type474 /*! \brief Mixture of mpdfs with constant weights, all mpdfs are of equal RV and RVC 475 475 476 476 */ 477 // class mmix : public mpdf { 478 // protected: 479 // //! Component (epdfs) 480 // Array<mpdf*> Coms; 481 // 482 // //!Internal epdf 483 // emix iepdf; 484 // 485 // public: 486 // //!Default constructor 487 // mmix() : iepdf ( ) { 488 // set_ep ( iepdf ); 489 // } 490 // 491 // //! Set weights \c w and components \c R 492 // void set_parameters ( const vec &w, const Array<mpdf*> &Coms ) { 493 // Array<epdf*> Eps ( Coms.length() ); 494 // 495 // for ( int i = 0; i < Coms.length(); i++ ) { 496 // Eps ( i ) = Coms ( i )->e(); 497 // } 498 // 499 // iepdf->set_parameters ( w, Eps ); 500 // } 501 // 502 // void condition ( const vec &cond ) { 503 // for ( int i = 0; i < Coms.length(); i++ ) { 504 // Coms ( i )->condition ( cond ); 505 // } 506 // }; 507 // }; 477 class mmix : public mpdf { 478 protected: 479 //! Component (mpdfs) 480 Array<shared_ptr<mpdf> > Coms; 481 //!weights of the components 482 vec w; 483 //! dummy epdfs 484 epdf dummy_epdf; 485 public: 486 //!Default constructor 487 mmix() : Coms(0), dummy_epdf() { set_ep(dummy_epdf); } 488 489 //! Set weights \c w and components \c R 490 void set_parameters ( const vec &w0, const Array<shared_ptr<mpdf> > &Coms0 ) { 491 //!\TODO check if all components are OK 492 Coms = Coms0; 493 w=w0; 494 495 set_rv(Coms(0)->_rv()); 496 set_rvc(Coms(0)->_rvc()); 497 } 498 double evallogcond (const vec &dt, const vec &cond) { 499 double ll=0.0; 500 for (int i=0;i<Coms.length();i++){ 501 ll+=Coms(i)->evallogcond(dt,cond); 502 } 503 return ll; 504 } 505 506 vec samplecond (const vec &cond); 507 508 }; 508 509 509 510 } -
library/bdm/stat/exp_family.cpp
r487 r488 305 305 } 306 306 307 void eEmp::set_statistics ( const vec &w0, const epdf *epdf0 ) {307 void eEmp::set_statistics ( const vec &w0, const epdf &epdf0 ) { 308 308 //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); 309 dim = epdf0 ->dimension();309 dim = epdf0.dimension(); 310 310 w = w0; 311 311 w /= sum ( w0 );//renormalize 312 312 n = w.length(); 313 313 samples.set_size ( n ); 314 dim = epdf0->dimension();315 314 316 315 for ( int i = 0; i < n; i++ ) { 317 samples ( i ) = epdf0 ->sample();316 samples ( i ) = epdf0.sample(); 318 317 } 319 318 } -
library/bdm/stat/exp_family.h
r487 r488 24 24 25 25 //! Global Uniform_RNG 26 26 extern Uniform_RNG UniRNG; 27 27 //! Global Normal_RNG 28 28 extern Normal_RNG NorRNG; 29 29 //! Global Gamma_RNG 30 31 32 33 34 35 36 37 38 39 40 30 extern Gamma_RNG GamRNG; 31 32 /*! 33 * \brief General conjugate exponential family posterior density. 34 35 * More?... 36 */ 37 38 class eEF : public epdf 39 { 40 public: 41 41 // eEF() :epdf() {}; 42 //! default constructor 43 eEF ( ) :epdf ( ) {}; 44 //! logarithm of the normalizing constant, \f$\mathcal{I}\f$ 45 virtual double lognc() const =0; 46 //!TODO decide if it is really needed 47 virtual void dupdate ( mat &v ) {it_error ( "Not implemented" );}; 48 //!Evaluate normalized log-probability 49 virtual double evallog_nn ( const vec &val ) const{it_error ( "Not implemented" );return 0.0;}; 50 //!Evaluate normalized log-probability 51 virtual double evallog ( const vec &val ) const { 52 double tmp; 53 tmp= evallog_nn ( val )-lognc(); 54 // it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); 55 return tmp;} 56 //!Evaluate normalized log-probability for many samples 57 virtual vec evallog_m ( const mat &Val ) const 58 { 59 vec x ( Val.cols() ); 60 for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evallog_nn ( Val.get_col ( i ) ) ;} 61 return x-lognc(); 42 //! default constructor 43 eEF () : epdf () {}; 44 //! logarithm of the normalizing constant, \f$\mathcal{I}\f$ 45 virtual double lognc() const = 0; 46 //!TODO decide if it is really needed 47 virtual void dupdate (mat &v) {it_error ("Not implemented");}; 48 //!Evaluate normalized log-probability 49 virtual double evallog_nn (const vec &val) const{it_error ("Not implemented");return 0.0;}; 50 //!Evaluate normalized log-probability 51 virtual double evallog (const vec &val) const { 52 double tmp; 53 tmp = evallog_nn (val) - lognc(); 54 // it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); 55 return tmp; 56 } 57 //!Evaluate normalized log-probability for many samples 58 virtual vec evallog_m (const mat &Val) const { 59 vec x (Val.cols()); 60 for (int i = 0;i < Val.cols();i++) {x (i) = evallog_nn (Val.get_col (i)) ;} 61 return x -lognc(); 62 } 63 //!Evaluate normalized log-probability for many samples 64 virtual vec evallog_m (const Array<vec> &Val) const { 65 vec x (Val.length()); 66 for (int i = 0;i < Val.length();i++) {x (i) = evallog_nn (Val (i)) ;} 67 return x -lognc(); 68 } 69 //!Power of the density, used e.g. to flatten the density 70 virtual void pow (double p) {it_error ("Not implemented");}; 71 }; 72 73 74 //! Estimator for Exponential family 75 class BMEF : public BM 76 { 77 protected: 78 //! forgetting factor 79 double frg; 80 //! cached value of lognc() in the previous step (used in evaluation of \c ll ) 81 double last_lognc; 82 public: 83 //! Default constructor (=empty constructor) 84 BMEF (double frg0 = 1.0) : BM (), frg (frg0) {} 85 //! Copy constructor 86 BMEF (const BMEF &B) : BM (B), frg (B.frg), last_lognc (B.last_lognc) {} 87 //!get statistics from another model 88 virtual void set_statistics (const BMEF* BM0) {it_error ("Not implemented");}; 89 //! Weighted update of sufficient statistics (Bayes rule) 90 virtual void bayes (const vec &data, const double w) {}; 91 //original Bayes 92 void bayes (const vec &dt); 93 //!Flatten the posterior according to the given BMEF (of the same type!) 94 virtual void flatten (const BMEF * B) {it_error ("Not implemented");} 95 //!Flatten the posterior as if to keep nu0 data 96 // virtual void flatten ( double nu0 ) {it_error ( "Not implemented" );} 97 98 BMEF* _copy_ () const {it_error ("function _copy_ not implemented for this BM"); return NULL;}; 99 }; 100 101 template<class sq_T, template <typename> class TEpdf > 102 class mlnorm; 103 104 /*! 105 * \brief Gaussian density with positive definite (decomposed) covariance matrix. 106 107 * More?... 108 */ 109 template<class sq_T> 110 class enorm : public eEF 111 { 112 protected: 113 //! mean value 114 vec mu; 115 //! Covariance matrix in decomposed form 116 sq_T R; 117 public: 118 //!\name Constructors 119 //!@{ 120 121 enorm () : eEF (), mu (), R () {}; 122 enorm (const vec &mu, const sq_T &R) {set_parameters (mu, R);} 123 void set_parameters (const vec &mu, const sq_T &R); 124 void from_setting (const Setting &root); 125 void validate() { 126 it_assert (mu.length() == R.rows(), "parameters mismatch"); 127 dim = mu.length(); 128 } 129 //!@} 130 131 //! \name Mathematical operations 132 //!@{ 133 134 //! dupdate in exponential form (not really handy) 135 void dupdate (mat &v, double nu = 1.0); 136 137 vec sample() const; 138 139 double evallog_nn (const vec &val) const; 140 double lognc () const; 141 vec mean() const {return mu;} 142 vec variance() const {return diag (R.to_mat());} 143 // mlnorm<sq_T>* condition ( const RV &rvn ) const ; <=========== fails to cmpile. Why? 144 mpdf* condition (const RV &rvn) const ; 145 enorm<sq_T>* marginal (const RV &rv) const; 146 // epdf* marginal ( const RV &rv ) const; 147 //!@} 148 149 //! \name Access to attributes 150 //!@{ 151 152 vec& _mu() {return mu;} 153 void set_mu (const vec mu0) { mu = mu0;} 154 sq_T& _R() {return R;} 155 const sq_T& _R() const {return R;} 156 //!@} 157 158 }; 159 UIREGISTER (enorm<chmat>); 160 UIREGISTER (enorm<ldmat>); 161 UIREGISTER (enorm<fsqmat>); 162 163 164 /*! 165 * \brief Gauss-inverse-Wishart density stored in LD form 166 167 * For \f$p\f$-variate densities, given rv.count() should be \f$p\times\f$ V.rows(). 168 * 169 */ 170 class egiw : public eEF 171 { 172 protected: 173 //! Extended information matrix of sufficient statistics 174 ldmat V; 175 //! Number of data records (degrees of freedom) of sufficient statistics 176 double nu; 177 //! Dimension of the output 178 int dimx; 179 //! Dimension of the regressor 180 int nPsi; 181 public: 182 //!\name Constructors 183 //!@{ 184 egiw() : eEF() {}; 185 egiw (int dimx0, ldmat V0, double nu0 = -1.0) : eEF() {set_parameters (dimx0, V0, nu0);}; 186 187 void set_parameters (int dimx0, ldmat V0, double nu0 = -1.0) { 188 dimx = dimx0; 189 nPsi = V0.rows() - dimx; 190 dim = dimx * (dimx + nPsi); // size(R) + size(Theta) 191 192 V = V0; 193 if (nu0 < 0) { 194 nu = 0.1 + nPsi + 2 * dimx + 2; // +2 assures finite expected value of R 195 // terms before that are sufficient for finite normalization 196 } else { 197 nu = nu0; 62 198 } 63 //!Power of the density, used e.g. to flatten the density 64 virtual void pow ( double p ) {it_error ( "Not implemented" );}; 65 }; 66 67 68 //! Estimator for Exponential family 69 class BMEF : public BM 70 { 71 protected: 72 //! forgetting factor 73 double frg; 74 //! cached value of lognc() in the previous step (used in evaluation of \c ll ) 75 double last_lognc; 76 public: 77 //! Default constructor (=empty constructor) 78 BMEF ( double frg0=1.0 ) :BM ( ), frg ( frg0 ) {} 79 //! Copy constructor 80 BMEF ( const BMEF &B ) :BM ( B ), frg ( B.frg ), last_lognc ( B.last_lognc ) {} 81 //!get statistics from another model 82 virtual void set_statistics ( const BMEF* BM0 ) {it_error ( "Not implemented" );}; 83 //! Weighted update of sufficient statistics (Bayes rule) 84 virtual void bayes ( const vec &data, const double w ) {}; 85 //original Bayes 86 void bayes ( const vec &dt ); 87 //!Flatten the posterior according to the given BMEF (of the same type!) 88 virtual void flatten ( const BMEF * B ) {it_error ( "Not implemented" );} 89 //!Flatten the posterior as if to keep nu0 data 90 // virtual void flatten ( double nu0 ) {it_error ( "Not implemented" );} 91 92 BMEF* _copy_ () const {it_error ( "function _copy_ not implemented for this BM" ); return NULL;}; 93 }; 94 95 template<class sq_T, template <typename> class TEpdf > 96 class mlnorm; 97 98 /*! 99 * \brief Gaussian density with positive definite (decomposed) covariance matrix. 100 101 * More?... 102 */ 103 template<class sq_T> 104 class enorm : public eEF 105 { 106 protected: 107 //! mean value 108 vec mu; 109 //! Covariance matrix in decomposed form 110 sq_T R; 111 public: 112 //!\name Constructors 113 //!@{ 114 115 enorm ( ) :eEF ( ), mu ( ),R ( ) {}; 116 enorm ( const vec &mu,const sq_T &R ) {set_parameters ( mu,R );} 117 void set_parameters ( const vec &mu,const sq_T &R ); 118 void from_setting(const Setting &root); 119 void validate() { 120 it_assert(mu.length()==R.rows(),"parameters mismatch"); 121 dim = mu.length(); 199 } 200 //!@} 201 202 vec sample() const; 203 vec mean() const; 204 vec variance() const; 205 206 //! LS estimate of \f$\theta\f$ 207 vec est_theta() const; 208 209 //! Covariance of the LS estimate 210 ldmat est_theta_cov() const; 211 212 void mean_mat (mat &M, mat&R) const; 213 //! In this instance, val= [theta, r]. For multivariate instances, it is stored columnwise val = [theta_1 theta_2 ... r_1 r_2 ] 214 double evallog_nn (const vec &val) const; 215 double lognc () const; 216 void pow (double p) {V *= p;nu *= p;}; 217 218 //! \name Access attributes 219 //!@{ 220 221 ldmat& _V() {return V;} 222 const ldmat& _V() const {return V;} 223 double& _nu() {return nu;} 224 const double& _nu() const {return nu;} 225 void from_setting (const Setting &set) { 226 UI::get (nu, set, "nu", UI::compulsory); 227 UI::get (dimx, set, "dimx", UI::compulsory); 228 mat V; 229 UI::get (V, set, "V", UI::compulsory); 230 set_parameters (dimx, V, nu); 231 RV* rv = UI::build<RV> (set, "rv", UI::compulsory); 232 set_rv (*rv); 233 delete rv; 234 } 235 //!@} 236 }; 237 UIREGISTER (egiw); 238 239 /*! \brief Dirichlet posterior density 240 241 Continuous Dirichlet density of \f$n\f$-dimensional variable \f$x\f$ 242 \f[ 243 f(x|\beta) = \frac{\Gamma[\gamma]}{\prod_{i=1}^{n}\Gamma(\beta_i)} \prod_{i=1}^{n}x_i^{\beta_i-1} 244 \f] 245 where \f$\gamma=\sum_i \beta_i\f$. 246 */ 247 class eDirich: public eEF 248 { 249 protected: 250 //!sufficient statistics 251 vec beta; 252 public: 253 //!\name Constructors 254 //!@{ 255 256 eDirich () : eEF () {}; 257 eDirich (const eDirich &D0) : eEF () {set_parameters (D0.beta);}; 258 eDirich (const vec &beta0) {set_parameters (beta0);}; 259 void set_parameters (const vec &beta0) { 260 beta = beta0; 261 dim = beta.length(); 262 } 263 //!@} 264 265 vec sample() const {it_error ("Not implemented");return vec_1 (0.0);}; 266 vec mean() const {return beta / sum (beta);}; 267 vec variance() const {double gamma = sum (beta); return elem_mult (beta, (beta + 1)) / (gamma* (gamma + 1));} 268 //! In this instance, val is ... 269 double evallog_nn (const vec &val) const { 270 double tmp; tmp = (beta - 1) * log (val); 271 // it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); 272 return tmp; 273 }; 274 double lognc () const { 275 double tmp; 276 double gam = sum (beta); 277 double lgb = 0.0; 278 for (int i = 0;i < beta.length();i++) {lgb += lgamma (beta (i));} 279 tmp = lgb - lgamma (gam); 280 // it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); 281 return tmp; 282 }; 283 //!access function 284 vec& _beta() {return beta;} 285 //!Set internal parameters 286 }; 287 288 //! \brief Estimator for Multinomial density 289 class multiBM : public BMEF 290 { 291 protected: 292 //! Conjugate prior and posterior 293 eDirich est; 294 //! Pointer inside est to sufficient statistics 295 vec β 296 public: 297 //!Default constructor 298 multiBM () : BMEF (), est (), beta (est._beta()) { 299 if (beta.length() > 0) {last_lognc = est.lognc();} 300 else{last_lognc = 0.0;} 301 } 302 //!Copy constructor 303 multiBM (const multiBM &B) : BMEF (B), est (B.est), beta (est._beta()) {} 304 //! Sets sufficient statistics to match that of givefrom mB0 305 void set_statistics (const BM* mB0) {const multiBM* mB = dynamic_cast<const multiBM*> (mB0); beta = mB->beta;} 306 void bayes (const vec &dt) { 307 if (frg < 1.0) {beta *= frg;last_lognc = est.lognc();} 308 beta += dt; 309 if (evalll) {ll = est.lognc() - last_lognc;} 310 } 311 double logpred (const vec &dt) const { 312 eDirich pred (est); 313 vec &beta = pred._beta(); 314 315 double lll; 316 if (frg < 1.0) 317 {beta *= frg;lll = pred.lognc();} 318 else 319 if (evalll) {lll = last_lognc;} 320 else{lll = pred.lognc();} 321 322 beta += dt; 323 return pred.lognc() - lll; 324 } 325 void flatten (const BMEF* B) { 326 const multiBM* E = dynamic_cast<const multiBM*> (B); 327 // sum(beta) should be equal to sum(B.beta) 328 const vec &Eb = E->beta;//const_cast<multiBM*> ( E )->_beta(); 329 beta *= (sum (Eb) / sum (beta)); 330 if (evalll) {last_lognc = est.lognc();} 331 } 332 const epdf& posterior() const {return est;}; 333 const eDirich* _e() const {return &est;}; 334 void set_parameters (const vec &beta0) { 335 est.set_parameters (beta0); 336 if (evalll) {last_lognc = est.lognc();} 337 } 338 }; 339 340 /*! 341 \brief Gamma posterior density 342 343 Multivariate Gamma density as product of independent univariate densities. 344 \f[ 345 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i) 346 \f] 347 */ 348 349 class egamma : public eEF 350 { 351 protected: 352 //! Vector \f$\alpha\f$ 353 vec alpha; 354 //! Vector \f$\beta\f$ 355 vec beta; 356 public : 357 //! \name Constructors 358 //!@{ 359 egamma () : eEF (), alpha (0), beta (0) {}; 360 egamma (const vec &a, const vec &b) {set_parameters (a, b);}; 361 void set_parameters (const vec &a, const vec &b) {alpha = a, beta = b;dim = alpha.length();}; 362 //!@} 363 364 vec sample() const; 365 //! TODO: is it used anywhere? 366 // mat sample ( int N ) const; 367 double evallog (const vec &val) const; 368 double lognc () const; 369 //! Returns poiter to alpha and beta. Potentially dengerous: use with care! 370 vec& _alpha() {return alpha;} 371 vec& _beta() {return beta;} 372 vec mean() const {return elem_div (alpha, beta);} 373 vec variance() const {return elem_div (alpha, elem_mult (beta, beta)); } 374 375 //! Load from structure with elements: 376 //! \code 377 //! { alpha = [...]; // vector of alpha 378 //! beta = [...]; // vector of beta 379 //! rv = {class="RV",...} // description 380 //! } 381 //! \endcode 382 //!@} 383 void from_setting (const Setting &set) { 384 epdf::from_setting (set); // reads rv 385 UI::get (alpha, set, "alpha", UI::compulsory); 386 UI::get (beta, set, "beta", UI::compulsory); 387 validate(); 388 } 389 void validate() { 390 it_assert (alpha.length() == beta.length(), "parameters do not match"); 391 dim = alpha.length(); 392 } 393 }; 394 UIREGISTER (egamma); 395 /*! 396 \brief Inverse-Gamma posterior density 397 398 Multivariate inverse-Gamma density as product of independent univariate densities. 399 \f[ 400 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i) 401 \f] 402 403 Vector \f$\beta\f$ has different meaning (in fact it is 1/beta as used in definition of iG) 404 405 Inverse Gamma can be converted to Gamma using \f[ 406 x\sim iG(a,b) => 1/x\sim G(a,1/b) 407 \f] 408 This relation is used in sampling. 409 */ 410 411 class eigamma : public egamma 412 { 413 protected: 414 public : 415 //! \name Constructors 416 //! All constructors are inherited 417 //!@{ 418 //!@} 419 420 vec sample() const {return 1.0 / egamma::sample();}; 421 //! Returns poiter to alpha and beta. Potentially dangerous: use with care! 422 vec mean() const {return elem_div (beta, alpha - 1);} 423 vec variance() const {vec mea = mean(); return elem_div (elem_mult (mea, mea), alpha - 2);} 424 }; 425 /* 426 //! Weighted mixture of epdfs with external owned components. 427 class emix : public epdf { 428 protected: 429 int n; 430 vec &w; 431 Array<epdf*> Coms; 432 public: 433 //! Default constructor 434 emix ( const RV &rv, vec &w0): epdf(rv), n(w0.length()), w(w0), Coms(n) {}; 435 void set_parameters( int &i, double wi, epdf* ep){w(i)=wi;Coms(i)=ep;} 436 vec mean(){vec pom; for(int i=0;i<n;i++){pom+=Coms(i)->mean()*w(i);} return pom;}; 437 vec sample() {it_error ( "Not implemented" );return 0;} 438 }; 439 */ 440 441 //! Uniform distributed density on a rectangular support 442 443 class euni: public epdf 444 { 445 protected: 446 //! lower bound on support 447 vec low; 448 //! upper bound on support 449 vec high; 450 //! internal 451 vec distance; 452 //! normalizing coefficients 453 double nk; 454 //! cache of log( \c nk ) 455 double lnk; 456 public: 457 //! \name Constructors 458 //!@{ 459 euni () : epdf () {} 460 euni (const vec &low0, const vec &high0) {set_parameters (low0, high0);} 461 void set_parameters (const vec &low0, const vec &high0) { 462 distance = high0 - low0; 463 it_assert_debug (min (distance) > 0.0, "bad support"); 464 low = low0; 465 high = high0; 466 nk = prod (1.0 / distance); 467 lnk = log (nk); 468 dim = low.length(); 469 } 470 //!@} 471 472 double eval (const vec &val) const {return nk;} 473 double evallog (const vec &val) const { 474 if (any (val < low) && any (val > high)) {return inf;} 475 else return lnk; 476 } 477 vec sample() const { 478 vec smp (dim); 479 #pragma omp critical 480 UniRNG.sample_vector (dim , smp); 481 return low + elem_mult (distance, smp); 482 } 483 //! set values of \c low and \c high 484 vec mean() const {return (high -low) / 2.0;} 485 vec variance() const {return (pow (high, 2) + pow (low, 2) + elem_mult (high, low)) / 3.0;} 486 //! Load from structure with elements: 487 //! \code 488 //! { high = [...]; // vector of upper bounds 489 //! low = [...]; // vector of lower bounds 490 //! rv = {class="RV",...} // description of RV 491 //! } 492 //! \endcode 493 //!@} 494 void from_setting (const Setting &set) { 495 epdf::from_setting (set); // reads rv and rvc 496 497 UI::get (high, set, "high", UI::compulsory); 498 UI::get (low, set, "low", UI::compulsory); 499 } 500 }; 501 502 503 /*! 504 \brief Normal distributed linear function with linear function of mean value; 505 506 Mean value \f$mu=A*rvc+mu_0\f$. 507 */ 508 template < class sq_T, template <typename> class TEpdf = enorm > 509 class mlnorm : public mpdf_internal< TEpdf<sq_T> > 510 { 511 protected: 512 //! Internal epdf that arise by conditioning on \c rvc 513 mat A; 514 vec mu_const; 515 // vec& _mu; //cached epdf.mu; !!!!!! WHY NOT? 516 public: 517 //! \name Constructors 518 //!@{ 519 mlnorm() : mpdf_internal< TEpdf<sq_T> >() {}; 520 mlnorm (const mat &A, const vec &mu0, const sq_T &R) : mpdf_internal< TEpdf<sq_T> >() { 521 set_parameters (A, mu0, R); 522 } 523 524 //! Set \c A and \c R 525 void set_parameters (const mat &A0, const vec &mu0, const sq_T &R0) { 526 it_assert_debug (A0.rows() == mu0.length(), ""); 527 it_assert_debug (A0.rows() == R0.rows(), ""); 528 529 this->iepdf.set_parameters (zeros (A0.rows()), R0); 530 A = A0; 531 mu_const = mu0; 532 this->dimc = A0.cols(); 533 } 534 //!@} 535 //! Set value of \c rvc . Result of this operation is stored in \c epdf use function \c _ep to access it. 536 void condition (const vec &cond) { 537 this->iepdf._mu() = A * cond + mu_const; 538 //R is already assigned; 539 } 540 541 //!access function 542 vec& _mu_const() {return mu_const;} 543 //!access function 544 mat& _A() {return A;} 545 //!access function 546 mat _R() { return this->iepdf._R().to_mat(); } 547 548 template<typename sq_M> 549 friend std::ostream &operator<< (std::ostream &os, mlnorm<sq_M, enorm> &ml); 550 551 void from_setting (const Setting &set) { 552 mpdf::from_setting (set); 553 554 UI::get (A, set, "A", UI::compulsory); 555 UI::get (mu_const, set, "const", UI::compulsory); 556 mat R0; 557 UI::get (R0, set, "R", UI::compulsory); 558 set_parameters (A, mu_const, R0); 559 }; 560 }; 561 UIREGISTER (mlnorm<ldmat>); 562 UIREGISTER (mlnorm<fsqmat>); 563 UIREGISTER (mlnorm<chmat>); 564 565 //! Mpdf with general function for mean value 566 template<class sq_T> 567 class mgnorm : public mpdf_internal< enorm< sq_T > > 568 { 569 protected: 570 // vec μ WHY NOT? 571 fnc* g; 572 public: 573 //!default constructor 574 mgnorm() : mpdf_internal<enorm<sq_T> >() { } 575 //!set mean function 576 inline void set_parameters (fnc* g0, const sq_T &R0); 577 inline void condition (const vec &cond); 578 579 580 /*! UI for mgnorm 581 582 The mgnorm is constructed from a structure with fields: 583 \code 584 system = { 585 type = "mgnorm"; 586 // function for mean value evolution 587 g = {type="fnc"; ... } 588 589 // variance 590 R = [1, 0, 591 0, 1]; 592 // --OR -- 593 dR = [1, 1]; 594 595 // == OPTIONAL == 596 597 // description of y variables 598 y = {type="rv"; names=["y", "u"];}; 599 // description of u variable 600 u = {type="rv"; names=[];} 601 }; 602 \endcode 603 604 Result if 605 */ 606 607 void from_setting (const Setting &set) { 608 fnc* g = UI::build<fnc> (set, "g", UI::compulsory); 609 610 mat R; 611 vec dR; 612 if (UI::get (dR, set, "dR")) 613 R = diag (dR); 614 else 615 UI::get (R, set, "R", UI::compulsory); 616 617 set_parameters (g, R); 618 } 619 }; 620 621 UIREGISTER (mgnorm<chmat>); 622 623 624 /*! (Approximate) Student t density with linear function of mean value 625 626 The internal epdf of this class is of the type of a Gaussian (enorm). 627 However, each conditioning is trying to assure the best possible approximation by taking into account the zeta function. See [] for reference. 628 629 Perhaps a moment-matching technique? 630 */ 631 class mlstudent : public mlnorm<ldmat, enorm> 632 { 633 protected: 634 ldmat Lambda; 635 ldmat &_R; 636 ldmat Re; 637 public: 638 mlstudent () : mlnorm<ldmat, enorm> (), 639 Lambda (), _R (iepdf._R()) {} 640 void set_parameters (const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0) { 641 it_assert_debug (A0.rows() == mu0.length(), ""); 642 it_assert_debug (R0.rows() == A0.rows(), ""); 643 644 iepdf.set_parameters (mu0, Lambda); // 645 A = A0; 646 mu_const = mu0; 647 Re = R0; 648 Lambda = Lambda0; 649 } 650 void condition (const vec &cond) { 651 iepdf._mu() = A * cond + mu_const; 652 double zeta; 653 //ugly hack! 654 if ( (cond.length() + 1) == Lambda.rows()) { 655 zeta = Lambda.invqform (concat (cond, vec_1 (1.0))); 656 } else { 657 zeta = Lambda.invqform (cond); 122 658 } 123 //!@} 124 125 //! \name Mathematical operations 126 //!@{ 127 128 //! dupdate in exponential form (not really handy) 129 void dupdate ( mat &v,double nu=1.0 ); 130 131 vec sample() const; 132 133 double evallog_nn ( const vec &val ) const; 134 double lognc () const; 135 vec mean() const {return mu;} 136 vec variance() const {return diag ( R.to_mat() );} 137 // mlnorm<sq_T>* condition ( const RV &rvn ) const ; <=========== fails to cmpile. Why? 138 mpdf* condition ( const RV &rvn ) const ; 139 enorm<sq_T>* marginal ( const RV &rv ) const; 140 // epdf* marginal ( const RV &rv ) const; 141 //!@} 142 143 //! \name Access to attributes 144 //!@{ 145 146 vec& _mu() {return mu;} 147 void set_mu ( const vec mu0 ) { mu=mu0;} 148 sq_T& _R() {return R;} 149 const sq_T& _R() const {return R;} 150 //!@} 151 152 }; 153 UIREGISTER(enorm<chmat>); 154 UIREGISTER(enorm<ldmat>); 155 UIREGISTER(enorm<fsqmat>); 156 157 158 /*! 159 * \brief Gauss-inverse-Wishart density stored in LD form 160 161 * For \f$p\f$-variate densities, given rv.count() should be \f$p\times\f$ V.rows(). 162 * 163 */ 164 class egiw : public eEF 165 { 166 protected: 167 //! Extended information matrix of sufficient statistics 168 ldmat V; 169 //! Number of data records (degrees of freedom) of sufficient statistics 170 double nu; 171 //! Dimension of the output 172 int dimx; 173 //! Dimension of the regressor 174 int nPsi; 175 public: 176 //!\name Constructors 177 //!@{ 178 egiw() :eEF() {}; 179 egiw ( int dimx0, ldmat V0, double nu0=-1.0 ) :eEF() {set_parameters ( dimx0,V0, nu0 );}; 180 181 void set_parameters ( int dimx0, ldmat V0, double nu0=-1.0 ) 182 { 183 dimx=dimx0; 184 nPsi = V0.rows()-dimx; 185 dim = dimx* ( dimx+nPsi ); // size(R) + size(Theta) 186 187 V=V0; 188 if ( nu0<0 ) 189 { 190 nu = 0.1 +nPsi +2*dimx +2; // +2 assures finite expected value of R 191 // terms before that are sufficient for finite normalization 192 } 193 else 194 { 195 nu=nu0; 659 _R = Re; 660 _R *= (1 + zeta);// / ( nu ); << nu is in Re!!!!!! 661 }; 662 663 }; 664 /*! 665 \brief Gamma random walk 666 667 Mean value, \f$\mu\f$, of this density is given by \c rvc . 668 Standard deviation of the random walk is proportional to one \f$k\f$-th the mean. 669 This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$. 670 671 The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$. 672 */ 673 class mgamma : public mpdf_internal<egamma> 674 { 675 protected: 676 677 //! Constant \f$k\f$ 678 double k; 679 680 //! cache of iepdf.beta 681 vec &_beta; 682 683 public: 684 //! Constructor 685 mgamma() : mpdf_internal<egamma>(), k (0), 686 _beta (iepdf._beta()) { 687 } 688 689 //! Set value of \c k 690 void set_parameters (double k, const vec &beta0); 691 692 void condition (const vec &val) {_beta = k / val;}; 693 //! Load from structure with elements: 694 //! \code 695 //! { alpha = [...]; // vector of alpha 696 //! k = 1.1; // multiplicative constant k 697 //! rv = {class="RV",...} // description of RV 698 //! rvc = {class="RV",...} // description of RV in condition 699 //! } 700 //! \endcode 701 //!@} 702 void from_setting (const Setting &set) { 703 mpdf::from_setting (set); // reads rv and rvc 704 vec betatmp; // ugly but necessary 705 UI::get (betatmp, set, "beta", UI::compulsory); 706 UI::get (k, set, "k", UI::compulsory); 707 set_parameters (k, betatmp); 708 } 709 }; 710 UIREGISTER (mgamma); 711 712 /*! 713 \brief Inverse-Gamma random walk 714 715 Mean value, \f$ \mu \f$, of this density is given by \c rvc . 716 Standard deviation of the random walk is proportional to one \f$ k \f$-th the mean. 717 This is achieved by setting \f$ \alpha=\mu/k^2+2 \f$ and \f$ \beta=\mu(\alpha-1)\f$. 718 719 The standard deviation of the walk is then: \f$ \mu/\sqrt(k)\f$. 720 */ 721 class migamma : public mpdf_internal<eigamma> 722 { 723 protected: 724 //! Constant \f$k\f$ 725 double k; 726 727 //! cache of iepdf.alpha 728 vec &_alpha; 729 730 //! cache of iepdf.beta 731 vec &_beta; 732 733 public: 734 //! \name Constructors 735 //!@{ 736 migamma() : mpdf_internal<eigamma>(), 737 k (0), 738 _alpha (iepdf._alpha()), 739 _beta (iepdf._beta()) { 740 } 741 742 migamma (const migamma &m) : mpdf_internal<eigamma>(), 743 k (0), 744 _alpha (iepdf._alpha()), 745 _beta (iepdf._beta()) { 746 } 747 //!@} 748 749 //! Set value of \c k 750 void set_parameters (int len, double k0) { 751 k = k0; 752 iepdf.set_parameters ( (1.0 / (k*k) + 2.0) *ones (len) /*alpha*/, ones (len) /*beta*/); 753 dimc = dimension(); 754 }; 755 void condition (const vec &val) { 756 _beta = elem_mult (val, (_alpha - 1.0)); 757 }; 758 }; 759 760 761 /*! 762 \brief Gamma random walk around a fixed point 763 764 Mean value, \f$\mu\f$, of this density is given by a geometric combination of \c rvc and given fixed point, \f$p\f$. \f$l\f$ is the coefficient of the geometric combimation 765 \f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f] 766 767 Standard deviation of the random walk is proportional to one \f$k\f$-th the mean. 768 This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$. 769 770 The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$. 771 */ 772 class mgamma_fix : public mgamma 773 { 774 protected: 775 //! parameter l 776 double l; 777 //! reference vector 778 vec refl; 779 public: 780 //! Constructor 781 mgamma_fix () : mgamma (), refl () {}; 782 //! Set value of \c k 783 void set_parameters (double k0 , vec ref0, double l0) { 784 mgamma::set_parameters (k0, ref0); 785 refl = pow (ref0, 1.0 - l0);l = l0; 786 dimc = dimension(); 787 }; 788 789 void condition (const vec &val) {vec mean = elem_mult (refl, pow (val, l)); _beta = k / mean;}; 790 }; 791 792 793 /*! 794 \brief Inverse-Gamma random walk around a fixed point 795 796 Mean value, \f$\mu\f$, of this density is given by a geometric combination of \c rvc and given fixed point, \f$p\f$. \f$l\f$ is the coefficient of the geometric combimation 797 \f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f] 798 799 ==== Check == vv = 800 Standard deviation of the random walk is proportional to one \f$k\f$-th the mean. 801 This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$. 802 803 The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$. 804 */ 805 class migamma_ref : public migamma 806 { 807 protected: 808 //! parameter l 809 double l; 810 //! reference vector 811 vec refl; 812 public: 813 //! Constructor 814 migamma_ref () : migamma (), refl () {}; 815 //! Set value of \c k 816 void set_parameters (double k0 , vec ref0, double l0) { 817 migamma::set_parameters (ref0.length(), k0); 818 refl = pow (ref0, 1.0 - l0); 819 l = l0; 820 dimc = dimension(); 821 }; 822 823 void condition (const vec &val) { 824 vec mean = elem_mult (refl, pow (val, l)); 825 migamma::condition (mean); 826 }; 827 828 /*! UI for migamma_ref 829 830 The migamma_ref is constructed from a structure with fields: 831 \code 832 system = { 833 type = "migamma_ref"; 834 ref = [1e-5; 1e-5; 1e-2 1e-3]; // reference vector 835 l = 0.999; // constant l 836 k = 0.1; // constant k 837 838 // == OPTIONAL == 839 // description of y variables 840 y = {type="rv"; names=["y", "u"];}; 841 // description of u variable 842 u = {type="rv"; names=[];} 843 }; 844 \endcode 845 846 Result if 847 */ 848 void from_setting (const Setting &set); 849 850 // TODO dodelat void to_setting( Setting &set ) const; 851 }; 852 853 854 UIREGISTER (migamma_ref); 855 856 /*! Log-Normal probability density 857 only allow diagonal covariances! 858 859 Density of the form \f$ \log(x)\sim \mathcal{N}(\mu,\sigma^2) \f$ , i.e. 860 \f[ 861 x \sim \frac{1}{x\sigma\sqrt{2\pi}}\exp{-\frac{1}{2\sigma^2}(\log(x)-\mu)} 862 \f] 863 864 */ 865 class elognorm: public enorm<ldmat> 866 { 867 public: 868 vec sample() const {return exp (enorm<ldmat>::sample());}; 869 vec mean() const {vec var = enorm<ldmat>::variance();return exp (mu - 0.5*var);}; 870 871 }; 872 873 /*! 874 \brief Log-Normal random walk 875 876 Mean value, \f$\mu\f$, is... 877 878 ==== Check == vv = 879 Standard deviation of the random walk is proportional to one \f$k\f$-th the mean. 880 This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$. 881 882 The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$. 883 */ 884 class mlognorm : public mpdf_internal<elognorm> 885 { 886 protected: 887 //! parameter 1/2*sigma^2 888 double sig2; 889 890 //! access 891 vec μ 892 public: 893 //! Constructor 894 mlognorm() : mpdf_internal<elognorm>(), 895 sig2 (0), 896 mu (iepdf._mu()) { 897 } 898 899 //! Set value of \c k 900 void set_parameters (int size, double k) { 901 sig2 = 0.5 * log (k * k + 1); 902 iepdf.set_parameters (zeros (size), 2*sig2*eye (size)); 903 904 dimc = size; 905 }; 906 907 void condition (const vec &val) { 908 mu = log (val) - sig2;//elem_mult ( refl,pow ( val,l ) ); 909 }; 910 911 /*! UI for mlognorm 912 913 The mlognorm is constructed from a structure with fields: 914 \code 915 system = { 916 type = "mlognorm"; 917 k = 0.1; // constant k 918 mu0 = [1., 1.]; 919 920 // == OPTIONAL == 921 // description of y variables 922 y = {type="rv"; names=["y", "u"];}; 923 // description of u variable 924 u = {type="rv"; names=[];} 925 }; 926 \endcode 927 928 */ 929 void from_setting (const Setting &set); 930 931 // TODO dodelat void to_setting( Setting &set ) const; 932 933 }; 934 935 UIREGISTER (mlognorm); 936 937 /*! inverse Wishart density defined on Choleski decomposition 938 939 */ 940 class eWishartCh : public epdf 941 { 942 protected: 943 //! Upper-Triagle of Choleski decomposition of \f$ \Psi \f$ 944 chmat Y; 945 //! dimension of matrix \f$ \Psi \f$ 946 int p; 947 //! degrees of freedom \f$ \nu \f$ 948 double delta; 949 public: 950 void set_parameters (const mat &Y0, const double delta0) {Y = chmat (Y0);delta = delta0; p = Y.rows(); dim = p * p; } 951 mat sample_mat() const { 952 mat X = zeros (p, p); 953 954 //sample diagonal 955 for (int i = 0;i < p;i++) { 956 GamRNG.setup (0.5* (delta - i) , 0.5); // no +1 !! index if from 0 957 #pragma omp critical 958 X (i, i) = sqrt (GamRNG()); 959 } 960 //do the rest 961 for (int i = 0;i < p;i++) { 962 for (int j = i + 1;j < p;j++) { 963 #pragma omp critical 964 X (i, j) = NorRNG.sample(); 196 965 } 197 966 } 198 //!@} 199 200 vec sample() const; 201 vec mean() const; 202 vec variance() const; 203 204 //! LS estimate of \f$\theta\f$ 205 vec est_theta() const; 206 207 //! Covariance of the LS estimate 208 ldmat est_theta_cov() const; 209 210 void mean_mat ( mat &M, mat&R ) const; 211 //! In this instance, val= [theta, r]. For multivariate instances, it is stored columnwise val = [theta_1 theta_2 ... r_1 r_2 ] 212 double evallog_nn ( const vec &val ) const; 213 double lognc () const; 214 void pow ( double p ) {V*=p;nu*=p;}; 215 216 //! \name Access attributes 217 //!@{ 218 219 ldmat& _V() {return V;} 220 const ldmat& _V() const {return V;} 221 double& _nu() {return nu;} 222 const double& _nu() const {return nu;} 223 void from_setting(const Setting &set){ 224 UI::get(nu, set, "nu", UI::compulsory); 225 UI::get(dimx, set, "dimx", UI::compulsory); 226 mat V; 227 UI::get(V,set,"V", UI::compulsory); 228 set_parameters(dimx, V, nu); 229 RV* rv=UI::build<RV>(set,"rv", UI::compulsory); 230 set_rv(*rv); 231 delete rv; 967 return X*Y._Ch();// return upper triangular part of the decomposition 968 } 969 vec sample () const { 970 return vec (sample_mat()._data(), p*p); 971 } 972 //! fast access function y0 will be copied into Y.Ch. 973 void setY (const mat &Ch0) {copy_vector (dim, Ch0._data(), Y._Ch()._data());} 974 //! fast access function y0 will be copied into Y.Ch. 975 void _setY (const vec &ch0) {copy_vector (dim, ch0._data(), Y._Ch()._data()); } 976 //! access function 977 const chmat& getY() const {return Y;} 978 }; 979 980 class eiWishartCh: public epdf 981 { 982 protected: 983 eWishartCh W; 984 int p; 985 double delta; 986 public: 987 void set_parameters (const mat &Y0, const double delta0) { 988 delta = delta0; 989 W.set_parameters (inv (Y0), delta0); 990 dim = W.dimension(); p = Y0.rows(); 991 } 992 vec sample() const {mat iCh; iCh = inv (W.sample_mat()); return vec (iCh._data(), dim);} 993 void _setY (const vec &y0) { 994 mat Ch (p, p); 995 mat iCh (p, p); 996 copy_vector (dim, y0._data(), Ch._data()); 997 998 iCh = inv (Ch); 999 W.setY (iCh); 1000 } 1001 virtual double evallog (const vec &val) const { 1002 chmat X (p); 1003 const chmat& Y = W.getY(); 1004 1005 copy_vector (p*p, val._data(), X._Ch()._data()); 1006 chmat iX (p);X.inv (iX); 1007 // compute 1008 // \frac{ |\Psi|^{m/2}|X|^{-(m+p+1)/2}e^{-tr(\Psi X^{-1})/2} }{ 2^{mp/2}\Gamma_p(m/2)}, 1009 mat M = Y.to_mat() * iX.to_mat(); 1010 1011 double log1 = 0.5 * p * (2 * Y.logdet()) - 0.5 * (delta + p + 1) * (2 * X.logdet()) - 0.5 * trace (M); 1012 //Fixme! Multivariate gamma omitted!! it is ok for sampling, but not otherwise!! 1013 1014 /* if (0) { 1015 mat XX=X.to_mat(); 1016 mat YY=Y.to_mat(); 1017 1018 double log2 = 0.5*p*log(det(YY))-0.5*(delta+p+1)*log(det(XX))-0.5*trace(YY*inv(XX)); 1019 cout << log1 << "," << log2 << endl; 1020 }*/ 1021 return log1; 1022 }; 1023 1024 }; 1025 1026 class rwiWishartCh : public mpdf 1027 { 1028 protected: 1029 eiWishartCh eiW; 1030 //!square root of \f$ \nu-p-1 \f$ - needed for computation of \f$ \Psi \f$ from conditions 1031 double sqd; 1032 //reference point for diagonal 1033 vec refl; 1034 double l; 1035 int p; 1036 1037 public: 1038 rwiWishartCh() : eiW(), 1039 sqd (0), l (0), p (0) { 1040 set_ep (eiW); 1041 } 1042 1043 void set_parameters (int p0, double k, vec ref0, double l0) { 1044 p = p0; 1045 double delta = 2 / (k * k) + p + 3; 1046 sqd = sqrt (delta - p - 1); 1047 l = l0; 1048 refl = pow (ref0, 1 - l); 1049 1050 eiW.set_parameters (eye (p), delta); 1051 dimc = eiW.dimension(); 1052 } 1053 void condition (const vec &c) { 1054 vec z = c; 1055 int ri = 0; 1056 for (int i = 0;i < p*p;i += (p + 1)) {//trace diagonal element 1057 z (i) = pow (z (i), l) * refl (ri); 1058 ri++; 232 1059 } 233 //!@} 234 }; 235 UIREGISTER(egiw); 236 237 /*! \brief Dirichlet posterior density 238 239 Continuous Dirichlet density of \f$n\f$-dimensional variable \f$x\f$ 240 \f[ 241 f(x|\beta) = \frac{\Gamma[\gamma]}{\prod_{i=1}^{n}\Gamma(\beta_i)} \prod_{i=1}^{n}x_i^{\beta_i-1} 242 \f] 243 where \f$\gamma=\sum_i \beta_i\f$. 244 */ 245 class eDirich: public eEF 246 { 247 protected: 248 //!sufficient statistics 249 vec beta; 250 public: 251 //!\name Constructors 252 //!@{ 253 254 eDirich () : eEF ( ) {}; 255 eDirich ( const eDirich &D0 ) : eEF () {set_parameters ( D0.beta );}; 256 eDirich ( const vec &beta0 ) {set_parameters ( beta0 );}; 257 void set_parameters ( const vec &beta0 ) 258 { 259 beta= beta0; 260 dim = beta.length(); 261 } 262 //!@} 263 264 vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );}; 265 vec mean() const {return beta/sum(beta);}; 266 vec variance() const {double gamma =sum(beta); return elem_mult ( beta, ( beta+1 ) ) / ( gamma* ( gamma+1 ) );} 267 //! In this instance, val is ... 268 double evallog_nn ( const vec &val ) const 269 { 270 double tmp; tmp= ( beta-1 ) *log ( val ); 271 // it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); 272 return tmp; 273 }; 274 double lognc () const 275 { 276 double tmp; 277 double gam=sum ( beta ); 278 double lgb=0.0; 279 for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );} 280 tmp= lgb-lgamma ( gam ); 281 // it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); 282 return tmp; 283 }; 284 //!access function 285 vec& _beta() {return beta;} 286 //!Set internal parameters 287 }; 288 289 //! \brief Estimator for Multinomial density 290 class multiBM : public BMEF 291 { 292 protected: 293 //! Conjugate prior and posterior 294 eDirich est; 295 //! Pointer inside est to sufficient statistics 296 vec β 297 public: 298 //!Default constructor 299 multiBM ( ) : BMEF ( ),est ( ),beta ( est._beta() ) 300 { 301 if ( beta.length() >0 ) {last_lognc=est.lognc();} 302 else{last_lognc=0.0;} 303 } 304 //!Copy constructor 305 multiBM ( const multiBM &B ) : BMEF ( B ),est ( B.est ),beta ( est._beta() ) {} 306 //! Sets sufficient statistics to match that of givefrom mB0 307 void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;} 308 void bayes ( const vec &dt ) 309 { 310 if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();} 311 beta+=dt; 312 if ( evalll ) {ll=est.lognc()-last_lognc;} 313 } 314 double logpred ( const vec &dt ) const 315 { 316 eDirich pred ( est ); 317 vec &beta = pred._beta(); 318 319 double lll; 320 if ( frg<1.0 ) 321 {beta*=frg;lll=pred.lognc();} 322 else 323 if ( evalll ) {lll=last_lognc;} 324 else{lll=pred.lognc();} 325 326 beta+=dt; 327 return pred.lognc()-lll; 328 } 329 void flatten ( const BMEF* B ) 330 { 331 const multiBM* E=dynamic_cast<const multiBM*> ( B ); 332 // sum(beta) should be equal to sum(B.beta) 333 const vec &Eb=E->beta;//const_cast<multiBM*> ( E )->_beta(); 334 beta*= ( sum ( Eb ) /sum ( beta ) ); 335 if ( evalll ) {last_lognc=est.lognc();} 336 } 337 const epdf& posterior() const {return est;}; 338 const eDirich* _e() const {return &est;}; 339 void set_parameters ( const vec &beta0 ) 340 { 341 est.set_parameters ( beta0 ); 342 if ( evalll ) {last_lognc=est.lognc();} 343 } 344 }; 345 346 /*! 347 \brief Gamma posterior density 348 349 Multivariate Gamma density as product of independent univariate densities. 350 \f[ 351 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i) 352 \f] 353 */ 354 355 class egamma : public eEF 356 { 357 protected: 358 //! Vector \f$\alpha\f$ 359 vec alpha; 360 //! Vector \f$\beta\f$ 361 vec beta; 362 public : 363 //! \name Constructors 364 //!@{ 365 egamma ( ) :eEF ( ), alpha ( 0 ), beta ( 0 ) {}; 366 egamma ( const vec &a, const vec &b ) {set_parameters ( a, b );}; 367 void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;dim = alpha.length();}; 368 //!@} 369 370 vec sample() const; 371 //! TODO: is it used anywhere? 372 // mat sample ( int N ) const; 373 double evallog ( const vec &val ) const; 374 double lognc () const; 375 //! Returns poiter to alpha and beta. Potentially dengerous: use with care! 376 vec& _alpha() {return alpha;} 377 vec& _beta() {return beta;} 378 vec mean() const {return elem_div ( alpha,beta );} 379 vec variance() const {return elem_div ( alpha,elem_mult ( beta,beta ) ); } 380 381 //! Load from structure with elements: 382 //! \code 383 //! { alpha = [...]; // vector of alpha 384 //! beta = [...]; // vector of beta 385 //! rv = {class="RV",...} // description 386 //! } 387 //! \endcode 388 //!@} 389 void from_setting(const Setting &set){ 390 epdf::from_setting(set); // reads rv 391 UI::get(alpha,set,"alpha", UI::compulsory); 392 UI::get(beta,set,"beta", UI::compulsory); 393 validate(); 394 } 395 void validate(){ 396 it_assert(alpha.length() ==beta.length(), "parameters do not match"); 397 dim =alpha.length(); 398 } 399 }; 400 UIREGISTER(egamma); 401 /*! 402 \brief Inverse-Gamma posterior density 403 404 Multivariate inverse-Gamma density as product of independent univariate densities. 405 \f[ 406 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i) 407 \f] 408 409 Vector \f$\beta\f$ has different meaning (in fact it is 1/beta as used in definition of iG) 410 411 Inverse Gamma can be converted to Gamma using \f[ 412 x\sim iG(a,b) => 1/x\sim G(a,1/b) 413 \f] 414 This relation is used in sampling. 415 */ 416 417 class eigamma : public egamma 418 { 419 protected: 420 public : 421 //! \name Constructors 422 //! All constructors are inherited 423 //!@{ 424 //!@} 425 426 vec sample() const {return 1.0/egamma::sample();}; 427 //! Returns poiter to alpha and beta. Potentially dangerous: use with care! 428 vec mean() const {return elem_div ( beta,alpha-1 );} 429 vec variance() const {vec mea=mean(); return elem_div ( elem_mult ( mea,mea ),alpha-2 );} 430 }; 431 /* 432 //! Weighted mixture of epdfs with external owned components. 433 class emix : public epdf { 434 protected: 1060 1061 eiW._setY (sqd*z); 1062 } 1063 }; 1064 1065 //! Switch between various resampling methods. 1066 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 }; 1067 /*! 1068 \brief Weighted empirical density 1069 1070 Used e.g. in particle filters. 1071 */ 1072 class eEmp: public epdf 1073 { 1074 protected : 1075 //! Number of particles 435 1076 int n; 436 vec &w; 437 Array<epdf*> Coms; 438 public: 439 //! Default constructor 440 emix ( const RV &rv, vec &w0): epdf(rv), n(w0.length()), w(w0), Coms(n) {}; 441 void set_parameters( int &i, double wi, epdf* ep){w(i)=wi;Coms(i)=ep;} 442 vec mean(){vec pom; for(int i=0;i<n;i++){pom+=Coms(i)->mean()*w(i);} return pom;}; 443 vec sample() {it_error ( "Not implemented" );return 0;} 444 }; 445 */ 446 447 //! Uniform distributed density on a rectangular support 448 449 class euni: public epdf 450 { 451 protected: 452 //! lower bound on support 453 vec low; 454 //! upper bound on support 455 vec high; 456 //! internal 457 vec distance; 458 //! normalizing coefficients 459 double nk; 460 //! cache of log( \c nk ) 461 double lnk; 462 public: 463 //! \name Constructors 464 //!@{ 465 euni ( ) :epdf ( ) {} 466 euni ( const vec &low0, const vec &high0 ) {set_parameters ( low0,high0 );} 467 void set_parameters ( const vec &low0, const vec &high0 ) 468 { 469 distance = high0-low0; 470 it_assert_debug ( min ( distance ) >0.0,"bad support" ); 471 low = low0; 472 high = high0; 473 nk = prod ( 1.0/distance ); 474 lnk = log ( nk ); 475 dim = low.length(); 476 } 477 //!@} 478 479 double eval ( const vec &val ) const {return nk;} 480 double evallog ( const vec &val ) const { 481 if (any(val<low) && any(val>high)) {return inf;} 482 else return lnk; 483 } 484 vec sample() const 485 { 486 vec smp ( dim ); 487 #pragma omp critical 488 UniRNG.sample_vector ( dim ,smp ); 489 return low+elem_mult ( distance,smp ); 490 } 491 //! set values of \c low and \c high 492 vec mean() const {return ( high-low ) /2.0;} 493 vec variance() const {return ( pow ( high,2 ) +pow ( low,2 ) +elem_mult ( high,low ) ) /3.0;} 494 //! Load from structure with elements: 495 //! \code 496 //! { high = [...]; // vector of upper bounds 497 //! low = [...]; // vector of lower bounds 498 //! rv = {class="RV",...} // description of RV 499 //! } 500 //! \endcode 501 //!@} 502 void from_setting(const Setting &set){ 503 epdf::from_setting(set); // reads rv and rvc 504 505 UI::get(high,set,"high", UI::compulsory); 506 UI::get(low,set,"low", UI::compulsory); 507 } 508 }; 509 510 511 /*! 512 \brief Normal distributed linear function with linear function of mean value; 513 514 Mean value \f$mu=A*rvc+mu_0\f$. 515 */ 516 template<class sq_T, template <typename> class TEpdf =enorm> 517 class mlnorm : public mpdf_internal< TEpdf<sq_T> > 518 { 519 protected: 520 //! Internal epdf that arise by conditioning on \c rvc 521 mat A; 522 vec mu_const; 523 // vec& _mu; //cached epdf.mu; !!!!!! WHY NOT? 524 public: 525 //! \name Constructors 526 //!@{ 527 mlnorm():mpdf_internal< TEpdf<sq_T> >() {}; 528 mlnorm (const mat &A, const vec &mu0, const sq_T &R ) : mpdf_internal< TEpdf<sq_T> >() 529 { 530 set_parameters ( A,mu0,R ); 531 } 532 533 //! Set \c A and \c R 534 void set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 ){ 535 it_assert_debug ( A0.rows() ==mu0.length(),"" ); 536 it_assert_debug ( A0.rows() ==R0.rows(),"" ); 537 538 this->iepdf.set_parameters(zeros(A0.rows()), R0); 539 A = A0; 540 mu_const = mu0; 541 this->dimc = A0.cols(); 542 } 543 //!@} 544 //! Set value of \c rvc . Result of this operation is stored in \c epdf use function \c _ep to access it. 545 void condition ( const vec &cond ){ 546 this->iepdf._mu()= A*cond + mu_const; 547 //R is already assigned; 548 } 549 550 //!access function 551 vec& _mu_const() {return mu_const;} 552 //!access function 553 mat& _A() {return A;} 554 //!access function 555 mat _R(){ return this->iepdf._R().to_mat(); } 556 557 template<typename sq_M> 558 friend std::ostream &operator<< ( std::ostream &os, mlnorm<sq_M,enorm> &ml ); 559 560 void from_setting(const Setting &set){ 561 mpdf::from_setting(set); 562 563 UI::get(A,set,"A", UI::compulsory); 564 UI::get(mu_const,set,"const", UI::compulsory); 565 mat R0; 566 UI::get(R0,set,"R", UI::compulsory); 567 set_parameters(A,mu_const,R0); 568 }; 569 }; 570 UIREGISTER(mlnorm<ldmat>); 571 UIREGISTER(mlnorm<fsqmat>); 572 UIREGISTER(mlnorm<chmat>); 573 574 //! Mpdf with general function for mean value 575 template<class sq_T> 576 class mgnorm : public mpdf_internal< enorm< sq_T > > 577 { 578 protected: 579 // vec μ WHY NOT? 580 fnc* g; 581 public: 582 //!default constructor 583 mgnorm():mpdf_internal<enorm<sq_T> >() { } 584 //!set mean function 585 inline void set_parameters ( fnc* g0, const sq_T &R0 ); 586 inline void condition ( const vec &cond ); 587 588 589 /*! UI for mgnorm 590 591 The mgnorm is constructed from a structure with fields: 592 \code 593 system = { 594 type = "mgnorm"; 595 // function for mean value evolution 596 g = {type="fnc"; ... } 597 598 // variance 599 R = [1, 0, 600 0, 1]; 601 // --OR -- 602 dR = [1, 1]; 603 604 // == OPTIONAL == 605 606 // description of y variables 607 y = {type="rv"; names=["y", "u"];}; 608 // description of u variable 609 u = {type="rv"; names=[];} 610 }; 611 \endcode 612 613 Result if 614 */ 615 616 void from_setting( const Setting &set ) 617 { 618 fnc* g = UI::build<fnc>( set, "g", UI::compulsory ); 619 620 mat R; 621 vec dR; 622 if ( UI::get( dR, set, "dR" ) ) 623 R=diag(dR); 624 else 625 UI::get( R, set, "R", UI::compulsory); 626 627 set_parameters(g,R); 628 } 629 }; 630 631 UIREGISTER(mgnorm<chmat>); 632 633 634 /*! (Approximate) Student t density with linear function of mean value 635 636 The internal epdf of this class is of the type of a Gaussian (enorm). 637 However, each conditioning is trying to assure the best possible approximation by taking into account the zeta function. See [] for reference. 638 639 Perhaps a moment-matching technique? 640 */ 641 class mlstudent : public mlnorm<ldmat,enorm> 642 { 643 protected: 644 ldmat Lambda; 645 ldmat &_R; 646 ldmat Re; 647 public: 648 mlstudent ( ) :mlnorm<ldmat,enorm> (), 649 Lambda (), _R ( iepdf._R() ) {} 650 void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0 ) 651 { 652 it_assert_debug ( A0.rows() ==mu0.length(),"" ); 653 it_assert_debug ( R0.rows() ==A0.rows(),"" ); 654 655 iepdf.set_parameters ( mu0,Lambda ); // 656 A = A0; 657 mu_const = mu0; 658 Re=R0; 659 Lambda = Lambda0; 660 } 661 void condition ( const vec &cond ) 662 { 663 iepdf._mu() = A*cond + mu_const; 664 double zeta; 665 //ugly hack! 666 if ( ( cond.length() +1 ) ==Lambda.rows() ) 667 { 668 zeta = Lambda.invqform ( concat ( cond, vec_1 ( 1.0 ) ) ); 669 } 670 else 671 { 672 zeta = Lambda.invqform ( cond ); 673 } 674 _R = Re; 675 _R*= ( 1+zeta );// / ( nu ); << nu is in Re!!!!!! 676 }; 677 678 }; 679 /*! 680 \brief Gamma random walk 681 682 Mean value, \f$\mu\f$, of this density is given by \c rvc . 683 Standard deviation of the random walk is proportional to one \f$k\f$-th the mean. 684 This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$. 685 686 The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$. 687 */ 688 class mgamma : public mpdf_internal<egamma> 689 { 690 protected: 691 692 //! Constant \f$k\f$ 693 double k; 694 695 //! cache of iepdf.beta 696 vec &_beta; 697 698 public: 699 //! Constructor 700 mgamma():mpdf_internal<egamma>(), k(0), 701 _beta(iepdf._beta()) { 702 } 703 704 //! Set value of \c k 705 void set_parameters(double k, const vec &beta0); 706 707 void condition ( const vec &val ) {_beta=k/val;}; 708 //! Load from structure with elements: 709 //! \code 710 //! { alpha = [...]; // vector of alpha 711 //! k = 1.1; // multiplicative constant k 712 //! rv = {class="RV",...} // description of RV 713 //! rvc = {class="RV",...} // description of RV in condition 714 //! } 715 //! \endcode 716 //!@} 717 void from_setting(const Setting &set){ 718 mpdf::from_setting(set); // reads rv and rvc 719 vec betatmp; // ugly but necessary 720 UI::get(betatmp,set,"beta", UI::compulsory); 721 UI::get(k,set,"k", UI::compulsory); 722 set_parameters(k,betatmp); 723 } 724 }; 725 UIREGISTER(mgamma); 726 727 /*! 728 \brief Inverse-Gamma random walk 729 730 Mean value, \f$ \mu \f$, of this density is given by \c rvc . 731 Standard deviation of the random walk is proportional to one \f$ k \f$-th the mean. 732 This is achieved by setting \f$ \alpha=\mu/k^2+2 \f$ and \f$ \beta=\mu(\alpha-1)\f$. 733 734 The standard deviation of the walk is then: \f$ \mu/\sqrt(k)\f$. 735 */ 736 class migamma : public mpdf_internal<eigamma> 737 { 738 protected: 739 //! Constant \f$k\f$ 740 double k; 741 742 //! cache of iepdf.alpha 743 vec &_alpha; 744 745 //! cache of iepdf.beta 746 vec &_beta; 747 748 public: 749 //! \name Constructors 750 //!@{ 751 migamma():mpdf_internal<eigamma>(), 752 k(0), 753 _alpha(iepdf._alpha()), 754 _beta(iepdf._beta()) { 755 } 756 757 migamma(const migamma &m):mpdf_internal<eigamma>(), 758 k(0), 759 _alpha(iepdf._alpha()), 760 _beta(iepdf._beta()) { 761 } 762 //!@} 763 764 //! Set value of \c k 765 void set_parameters ( int len, double k0 ) 766 { 767 k=k0; 768 iepdf.set_parameters ( ( 1.0/ ( k*k ) +2.0 ) *ones ( len ) /*alpha*/, ones ( len ) /*beta*/ ); 769 dimc = dimension(); 770 }; 771 void condition ( const vec &val ) 772 { 773 _beta=elem_mult ( val, ( _alpha-1.0 ) ); 774 }; 775 }; 776 777 778 /*! 779 \brief Gamma random walk around a fixed point 780 781 Mean value, \f$\mu\f$, of this density is given by a geometric combination of \c rvc and given fixed point, \f$p\f$. \f$l\f$ is the coefficient of the geometric combimation 782 \f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f] 783 784 Standard deviation of the random walk is proportional to one \f$k\f$-th the mean. 785 This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$. 786 787 The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$. 788 */ 789 class mgamma_fix : public mgamma 790 { 791 protected: 792 //! parameter l 793 double l; 794 //! reference vector 795 vec refl; 796 public: 797 //! Constructor 798 mgamma_fix ( ) : mgamma ( ),refl () {}; 799 //! Set value of \c k 800 void set_parameters ( double k0 , vec ref0, double l0 ) 801 { 802 mgamma::set_parameters ( k0, ref0 ); 803 refl=pow ( ref0,1.0-l0 );l=l0; 804 dimc=dimension(); 805 }; 806 807 void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); _beta=k/mean;}; 808 }; 809 810 811 /*! 812 \brief Inverse-Gamma random walk around a fixed point 813 814 Mean value, \f$\mu\f$, of this density is given by a geometric combination of \c rvc and given fixed point, \f$p\f$. \f$l\f$ is the coefficient of the geometric combimation 815 \f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f] 816 817 ==== Check == vv = 818 Standard deviation of the random walk is proportional to one \f$k\f$-th the mean. 819 This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$. 820 821 The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$. 822 */ 823 class migamma_ref : public migamma 824 { 825 protected: 826 //! parameter l 827 double l; 828 //! reference vector 829 vec refl; 830 public: 831 //! Constructor 832 migamma_ref ( ) : migamma (),refl ( ) {}; 833 //! Set value of \c k 834 void set_parameters ( double k0 , vec ref0, double l0 ) 835 { 836 migamma::set_parameters ( ref0.length(), k0 ); 837 refl=pow ( ref0,1.0-l0 ); 838 l=l0; 839 dimc = dimension(); 840 }; 841 842 void condition ( const vec &val ) 843 { 844 vec mean=elem_mult ( refl,pow ( val,l ) ); 845 migamma::condition ( mean ); 846 }; 847 848 /*! UI for migamma_ref 849 850 The migamma_ref is constructed from a structure with fields: 851 \code 852 system = { 853 type = "migamma_ref"; 854 ref = [1e-5; 1e-5; 1e-2 1e-3]; // reference vector 855 l = 0.999; // constant l 856 k = 0.1; // constant k 857 858 // == OPTIONAL == 859 // description of y variables 860 y = {type="rv"; names=["y", "u"];}; 861 // description of u variable 862 u = {type="rv"; names=[];} 863 }; 864 \endcode 865 866 Result if 867 */ 868 void from_setting( const Setting &set ); 869 870 // TODO dodelat void to_setting( Setting &set ) const; 871 }; 872 873 874 UIREGISTER(migamma_ref); 875 876 /*! Log-Normal probability density 877 only allow diagonal covariances! 878 879 Density of the form \f$ \log(x)\sim \mathcal{N}(\mu,\sigma^2) \f$ , i.e. 880 \f[ 881 x \sim \frac{1}{x\sigma\sqrt{2\pi}}\exp{-\frac{1}{2\sigma^2}(\log(x)-\mu)} 882 \f] 883 884 */ 885 class elognorm: public enorm<ldmat> 886 { 887 public: 888 vec sample() const {return exp ( enorm<ldmat>::sample() );}; 889 vec mean() const {vec var=enorm<ldmat>::variance();return exp ( mu - 0.5*var );}; 890 891 }; 892 893 /*! 894 \brief Log-Normal random walk 895 896 Mean value, \f$\mu\f$, is... 897 898 ==== Check == vv = 899 Standard deviation of the random walk is proportional to one \f$k\f$-th the mean. 900 This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$. 901 902 The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$. 903 */ 904 class mlognorm : public mpdf_internal<elognorm> 905 { 906 protected: 907 //! parameter 1/2*sigma^2 908 double sig2; 909 910 //! access 911 vec μ 912 public: 913 //! Constructor 914 mlognorm():mpdf_internal<elognorm>(), 915 sig2(0), 916 mu(iepdf._mu()) { 917 } 918 919 //! Set value of \c k 920 void set_parameters ( int size, double k ) 921 { 922 sig2 = 0.5*log ( k*k+1 ); 923 iepdf.set_parameters ( zeros ( size ),2*sig2*eye ( size ) ); 924 925 dimc = size; 926 }; 927 928 void condition ( const vec &val ) 929 { 930 mu=log ( val )-sig2;//elem_mult ( refl,pow ( val,l ) ); 931 }; 932 933 /*! UI for mlognorm 934 935 The mlognorm is constructed from a structure with fields: 936 \code 937 system = { 938 type = "mlognorm"; 939 k = 0.1; // constant k 940 mu0 = [1., 1.]; 941 942 // == OPTIONAL == 943 // description of y variables 944 y = {type="rv"; names=["y", "u"];}; 945 // description of u variable 946 u = {type="rv"; names=[];} 947 }; 948 \endcode 949 950 */ 951 void from_setting( const Setting &set ); 952 953 // TODO dodelat void to_setting( Setting &set ) const; 954 955 }; 956 957 UIREGISTER(mlognorm); 958 959 /*! inverse Wishart density defined on Choleski decomposition 960 961 */ 962 class eWishartCh : public epdf 963 { 964 protected: 965 //! Upper-Triagle of Choleski decomposition of \f$ \Psi \f$ 966 chmat Y; 967 //! dimension of matrix \f$ \Psi \f$ 968 int p; 969 //! degrees of freedom \f$ \nu \f$ 970 double delta; 971 public: 972 void set_parameters ( const mat &Y0, const double delta0 ) {Y=chmat ( Y0 );delta=delta0; p=Y.rows(); dim = p*p; } 973 mat sample_mat() const 974 { 975 mat X=zeros ( p,p ); 976 977 //sample diagonal 978 for ( int i=0;i<p;i++ ) 979 { 980 GamRNG.setup ( 0.5* ( delta-i ) , 0.5 ); // no +1 !! index if from 0 981 #pragma omp critical 982 X ( i,i ) =sqrt ( GamRNG() ); 983 } 984 //do the rest 985 for ( int i=0;i<p;i++ ) 986 { 987 for ( int j=i+1;j<p;j++ ) 988 { 989 #pragma omp critical 990 X ( i,j ) =NorRNG.sample(); 991 } 992 } 993 return X*Y._Ch();// return upper triangular part of the decomposition 994 } 995 vec sample () const 996 { 997 return vec ( sample_mat()._data(),p*p ); 998 } 999 //! fast access function y0 will be copied into Y.Ch. 1000 void setY ( const mat &Ch0 ) {copy_vector ( dim,Ch0._data(), Y._Ch()._data() );} 1001 //! fast access function y0 will be copied into Y.Ch. 1002 void _setY ( const vec &ch0 ) {copy_vector ( dim, ch0._data(), Y._Ch()._data() ); } 1003 //! access function 1004 const chmat& getY()const {return Y;} 1005 }; 1006 1007 class eiWishartCh: public epdf 1008 { 1009 protected: 1010 eWishartCh W; 1011 int p; 1012 double delta; 1013 public: 1014 void set_parameters ( const mat &Y0, const double delta0) { 1015 delta = delta0; 1016 W.set_parameters ( inv ( Y0 ),delta0 ); 1017 dim = W.dimension(); p=Y0.rows(); 1018 } 1019 vec sample() const {mat iCh; iCh=inv ( W.sample_mat() ); return vec ( iCh._data(),dim );} 1020 void _setY ( const vec &y0 ) 1021 { 1022 mat Ch ( p,p ); 1023 mat iCh ( p,p ); 1024 copy_vector ( dim, y0._data(), Ch._data() ); 1025 1026 iCh=inv ( Ch ); 1027 W.setY ( iCh ); 1028 } 1029 virtual double evallog ( const vec &val ) const { 1030 chmat X(p); 1031 const chmat& Y=W.getY(); 1032 1033 copy_vector(p*p,val._data(),X._Ch()._data()); 1034 chmat iX(p);X.inv(iX); 1035 // compute 1036 // \frac{ |\Psi|^{m/2}|X|^{-(m+p+1)/2}e^{-tr(\Psi X^{-1})/2} }{ 2^{mp/2}\Gamma_p(m/2)}, 1037 mat M=Y.to_mat()*iX.to_mat(); 1038 1039 double log1 = 0.5*p*(2*Y.logdet())-0.5*(delta+p+1)*(2*X.logdet())-0.5*trace(M); 1040 //Fixme! Multivariate gamma omitted!! it is ok for sampling, but not otherwise!! 1041 1042 /* if (0) { 1043 mat XX=X.to_mat(); 1044 mat YY=Y.to_mat(); 1045 1046 double log2 = 0.5*p*log(det(YY))-0.5*(delta+p+1)*log(det(XX))-0.5*trace(YY*inv(XX)); 1047 cout << log1 << "," << log2 << endl; 1048 }*/ 1049 return log1; 1050 }; 1051 1052 }; 1053 1054 class rwiWishartCh : public mpdf 1055 { 1056 protected: 1057 eiWishartCh eiW; 1058 //!square root of \f$ \nu-p-1 \f$ - needed for computation of \f$ \Psi \f$ from conditions 1059 double sqd; 1060 //reference point for diagonal 1061 vec refl; 1062 double l; 1063 int p; 1064 1065 public: 1066 rwiWishartCh():eiW(), 1067 sqd(0), l(0), p(0) { 1068 set_ep(eiW); 1069 } 1070 1071 void set_parameters ( int p0, double k, vec ref0, double l0 ) 1072 { 1073 p=p0; 1074 double delta = 2/(k*k)+p+3; 1075 sqd=sqrt ( delta-p-1 ); 1076 l=l0; 1077 refl=pow(ref0,1-l); 1078 1079 eiW.set_parameters ( eye ( p ),delta ); 1080 dimc=eiW.dimension(); 1081 } 1082 void condition ( const vec &c ) { 1083 vec z=c; 1084 int ri=0; 1085 for(int i=0;i<p*p;i+=(p+1)){//trace diagonal element 1086 z(i) = pow(z(i),l)*refl(ri); 1087 ri++; 1088 } 1089 1090 eiW._setY ( sqd*z ); 1091 } 1092 }; 1093 1094 //! Switch between various resampling methods. 1095 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 }; 1096 /*! 1097 \brief Weighted empirical density 1098 1099 Used e.g. in particle filters. 1100 */ 1101 class eEmp: public epdf 1102 { 1103 protected : 1104 //! Number of particles 1105 int n; 1106 //! Sample weights \f$w\f$ 1107 vec w; 1108 //! Samples \f$x^{(i)}, i=1..n\f$ 1109 Array<vec> samples; 1110 public: 1111 //! \name Constructors 1112 //!@{ 1113 eEmp ( ) :epdf ( ),w ( ),samples ( ) {}; 1114 //! copy constructor 1115 eEmp ( const eEmp &e ) : epdf ( e ), w ( e.w ), samples ( e.samples ) {}; 1116 //!@} 1117 1118 //! Set samples and weights 1119 void set_statistics ( const vec &w0, const epdf* pdf0 ); 1120 //! Set samples and weights 1121 void set_statistics ( const epdf* pdf0 , int n ) {set_statistics ( ones ( n ) /n,pdf0 );}; 1122 //! Set sample 1123 void set_samples ( const epdf* pdf0 ); 1124 //! Set sample 1125 void set_parameters ( int n0, bool copy=true ) {n=n0; w.set_size ( n0,copy );samples.set_size ( n0,copy );}; 1126 //! Potentially dangerous, use with care. 1127 vec& _w() {return w;}; 1128 //! Potentially dangerous, use with care. 1129 const vec& _w() const {return w;}; 1130 //! access function 1131 Array<vec>& _samples() {return samples;}; 1132 //! access function 1133 const Array<vec>& _samples() const {return samples;}; 1134 //! Function performs resampling, i.e. removal of low-weight samples and duplication of high-weight samples such that the new samples represent the same density. 1135 ivec resample ( RESAMPLING_METHOD method=SYSTEMATIC ); 1136 //! inherited operation : NOT implemneted 1137 vec sample() const {it_error ( "Not implemented" );return 0;} 1138 //! inherited operation : NOT implemneted 1139 double evallog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;} 1140 vec mean() const 1141 { 1142 vec pom=zeros ( dim ); 1143 for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );} 1144 return pom; 1145 } 1146 vec variance() const 1147 { 1148 vec pom=zeros ( dim ); 1149 for ( int i=0;i<n;i++ ) {pom+=pow ( samples ( i ),2 ) *w ( i );} 1150 return pom-pow ( mean(),2 ); 1151 } 1152 //! For this class, qbounds are minimum and maximum value of the population! 1153 void qbounds ( vec &lb, vec &ub, double perc=0.95 ) const 1154 { 1155 // lb in inf so than it will be pushed below; 1156 lb.set_size ( dim ); 1157 ub.set_size ( dim ); 1158 lb = std::numeric_limits<double>::infinity(); 1159 ub = -std::numeric_limits<double>::infinity(); 1160 int j; 1161 for ( int i=0;i<n;i++ ) 1162 { 1163 for ( j=0;j<dim; j++ ) 1164 { 1165 if ( samples ( i ) ( j ) <lb ( j ) ) {lb ( j ) =samples ( i ) ( j );} 1166 if ( samples ( i ) ( j ) >ub ( j ) ) {ub ( j ) =samples ( i ) ( j );} 1167 } 1077 //! Sample weights \f$w\f$ 1078 vec w; 1079 //! Samples \f$x^{(i)}, i=1..n\f$ 1080 Array<vec> samples; 1081 public: 1082 //! \name Constructors 1083 //!@{ 1084 eEmp () : epdf (), w (), samples () {}; 1085 //! copy constructor 1086 eEmp (const eEmp &e) : epdf (e), w (e.w), samples (e.samples) {}; 1087 //!@} 1088 1089 //! Set samples and weights 1090 void set_statistics (const vec &w0, const epdf &pdf0); 1091 //! Set samples and weights 1092 void set_statistics (const epdf &pdf0 , int n) {set_statistics (ones (n) / n, pdf0);}; 1093 //! Set sample 1094 void set_samples (const epdf* pdf0); 1095 //! Set sample 1096 void set_parameters (int n0, bool copy = true) {n = n0; w.set_size (n0, copy);samples.set_size (n0, copy);}; 1097 //! Potentially dangerous, use with care. 1098 vec& _w() {return w;}; 1099 //! Potentially dangerous, use with care. 1100 const vec& _w() const {return w;}; 1101 //! access function 1102 Array<vec>& _samples() {return samples;}; 1103 //! access function 1104 const Array<vec>& _samples() const {return samples;}; 1105 //! Function performs resampling, i.e. removal of low-weight samples and duplication of high-weight samples such that the new samples represent the same density. 1106 ivec resample (RESAMPLING_METHOD method = SYSTEMATIC); 1107 //! inherited operation : NOT implemneted 1108 vec sample() const {it_error ("Not implemented");return 0;} 1109 //! inherited operation : NOT implemneted 1110 double evallog (const vec &val) const {it_error ("Not implemented");return 0.0;} 1111 vec mean() const { 1112 vec pom = zeros (dim); 1113 for (int i = 0;i < n;i++) {pom += samples (i) * w (i);} 1114 return pom; 1115 } 1116 vec variance() const { 1117 vec pom = zeros (dim); 1118 for (int i = 0;i < n;i++) {pom += pow (samples (i), 2) * w (i);} 1119 return pom -pow (mean(), 2); 1120 } 1121 //! For this class, qbounds are minimum and maximum value of the population! 1122 void qbounds (vec &lb, vec &ub, double perc = 0.95) const { 1123 // lb in inf so than it will be pushed below; 1124 lb.set_size (dim); 1125 ub.set_size (dim); 1126 lb = std::numeric_limits<double>::infinity(); 1127 ub = -std::numeric_limits<double>::infinity(); 1128 int j; 1129 for (int i = 0;i < n;i++) { 1130 for (j = 0;j < dim; j++) { 1131 if (samples (i) (j) < lb (j)) {lb (j) = samples (i) (j);} 1132 if (samples (i) (j) > ub (j)) {ub (j) = samples (i) (j);} 1168 1133 } 1169 1134 } 1170 }; 1135 } 1136 }; 1171 1137 1172 1138 1173 1139 //////////////////////// 1174 1140 1175 1176 void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0)1177 1141 template<class sq_T> 1142 void enorm<sq_T>::set_parameters (const vec &mu0, const sq_T &R0) 1143 { 1178 1144 //Fixme test dimensions of mu0 and R0; 1179 mu = mu0; 1180 R = R0; 1181 validate(); 1182 }; 1183 1184 template<class sq_T> 1185 void enorm<sq_T>::from_setting(const Setting &set){ 1186 epdf::from_setting(set); //reads rv 1187 1188 UI::get(mu,set,"mu", UI::compulsory); 1189 mat Rtmp;// necessary for conversion 1190 UI::get(Rtmp,set,"R", UI::compulsory); 1191 R=Rtmp; // conversion 1192 validate(); 1193 } 1194 1195 template<class sq_T> 1196 void enorm<sq_T>::dupdate ( mat &v, double nu ) 1197 { 1198 // 1199 }; 1145 mu = mu0; 1146 R = R0; 1147 validate(); 1148 }; 1149 1150 template<class sq_T> 1151 void enorm<sq_T>::from_setting (const Setting &set) 1152 { 1153 epdf::from_setting (set); //reads rv 1154 1155 UI::get (mu, set, "mu", UI::compulsory); 1156 mat Rtmp;// necessary for conversion 1157 UI::get (Rtmp, set, "R", UI::compulsory); 1158 R = Rtmp; // conversion 1159 validate(); 1160 } 1161 1162 template<class sq_T> 1163 void enorm<sq_T>::dupdate (mat &v, double nu) 1164 { 1165 // 1166 }; 1200 1167 1201 1168 // template<class sq_T> … … 1204 1171 // }; 1205 1172 1206 1207 1208 1209 vec x ( dim);1173 template<class sq_T> 1174 vec enorm<sq_T>::sample() const 1175 { 1176 vec x (dim); 1210 1177 #pragma omp critical 1211 NorRNG.sample_vector ( dim,x);1212 vec smp = R.sqrt_mult ( x);1213 1214 1215 1216 1178 NorRNG.sample_vector (dim, x); 1179 vec smp = R.sqrt_mult (x); 1180 1181 smp += mu; 1182 return smp; 1183 }; 1217 1184 1218 1185 // template<class sq_T> … … 1224 1191 // }; 1225 1192 1226 1227 double enorm<sq_T>::evallog_nn ( const vec &val) const1228 1229 1230 double tmp=-0.5* ( R.invqform ( mu-val ));// - lognc();1231 1232 1233 1234 1235 1236 1237 1238 double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet());1239 1240 1193 template<class sq_T> 1194 double enorm<sq_T>::evallog_nn (const vec &val) const 1195 { 1196 // 1.83787706640935 = log(2pi) 1197 double tmp = -0.5 * (R.invqform (mu - val));// - lognc(); 1198 return tmp; 1199 }; 1200 1201 template<class sq_T> 1202 inline double enorm<sq_T>::lognc () const 1203 { 1204 // 1.83787706640935 = log(2pi) 1205 double tmp = 0.5 * (R.cols() * 1.83787706640935 + R.logdet()); 1206 return tmp; 1207 }; 1241 1208 1242 1209 … … 1267 1234 1268 1235 1269 1270 enorm<sq_T>* enorm<sq_T>::marginal ( const RV &rvn) const1271 1272 it_assert_debug ( isnamed(), "rv description is not assigned");1273 ivec irvn = rvn.dataind ( rv);1274 1275 sq_T Rn ( R,irvn );//select rows and columns of R1276 1277 1278 tmp->set_rv ( rvn);1279 tmp->set_parameters ( mu ( irvn ), Rn);1280 1281 1282 1283 1284 mpdf* enorm<sq_T>::condition ( const RV &rvn) const1285 1286 1287 it_assert_debug ( isnamed(),"rvs are not assigned");1288 1289 RV rvc = rv.subt ( rvn);1290 it_assert_debug ( ( rvc._dsize() +rvn._dsize() ==rv._dsize() ),"wrong rvn");1291 1292 ivec irvn = rvn.dataind ( rv);1293 ivec irvc = rvc.dataind ( rv);1294 ivec perm=concat ( irvn , irvc);1295 sq_T Rn ( R,perm);1296 1297 1298 mat S=Rn.to_mat();1299 1300 int n=rvn._dsize()-1;1301 int end=R.rows()-1;1302 mat S11 = S.get ( 0,n, 0, n);1303 mat S12 = S.get ( 0, n , rvn._dsize(), end);1304 mat S22 = S.get ( rvn._dsize(), end, rvn._dsize(), end);1305 1306 vec mu1 = mu ( irvn);1307 vec mu2 = mu ( irvc);1308 mat A=S12*inv ( S22);1309 sq_T R_n ( S11 - A *S12.T());1310 1311 mlnorm<sq_T>* tmp=new mlnorm<sq_T> ();1312 tmp->set_rv ( rvn ); tmp->set_rvc ( rvc);1313 tmp->set_parameters ( A,mu1-A*mu2,R_n);1314 1315 1316 1317 1318 1319 template<class sq_T> 1320 void mgnorm<sq_T >::set_parameters ( fnc* g0, const sq_T &R0 ) {g=g0; this->iepdf.set_parameters ( zeros ( g->dimension() ), R0);}1321 template<class sq_T> 1322 void mgnorm<sq_T >::condition ( const vec &cond ) {this->iepdf._mu()=g->eval ( cond);};1323 1324 1325 std::ostream &operator<< ( std::ostream &os, mlnorm<sq_T> &ml)1326 1327 os << "A:"<< ml.A<<endl;1328 os << "mu:"<< ml.mu_const<<endl;1329 os << "R:" << ml.iepdf->_R().to_mat() <<endl;1330 1331 1236 template<class sq_T> 1237 enorm<sq_T>* enorm<sq_T>::marginal (const RV &rvn) const 1238 { 1239 it_assert_debug (isnamed(), "rv description is not assigned"); 1240 ivec irvn = rvn.dataind (rv); 1241 1242 sq_T Rn (R, irvn); //select rows and columns of R 1243 1244 enorm<sq_T>* tmp = new enorm<sq_T>; 1245 tmp->set_rv (rvn); 1246 tmp->set_parameters (mu (irvn), Rn); 1247 return tmp; 1248 } 1249 1250 template<class sq_T> 1251 mpdf* enorm<sq_T>::condition (const RV &rvn) const 1252 { 1253 1254 it_assert_debug (isnamed(), "rvs are not assigned"); 1255 1256 RV rvc = rv.subt (rvn); 1257 it_assert_debug ( (rvc._dsize() + rvn._dsize() == rv._dsize()), "wrong rvn"); 1258 //Permutation vector of the new R 1259 ivec irvn = rvn.dataind (rv); 1260 ivec irvc = rvc.dataind (rv); 1261 ivec perm = concat (irvn , irvc); 1262 sq_T Rn (R, perm); 1263 1264 //fixme - could this be done in general for all sq_T? 1265 mat S = Rn.to_mat(); 1266 //fixme 1267 int n = rvn._dsize() - 1; 1268 int end = R.rows() - 1; 1269 mat S11 = S.get (0, n, 0, n); 1270 mat S12 = S.get (0, n , rvn._dsize(), end); 1271 mat S22 = S.get (rvn._dsize(), end, rvn._dsize(), end); 1272 1273 vec mu1 = mu (irvn); 1274 vec mu2 = mu (irvc); 1275 mat A = S12 * inv (S22); 1276 sq_T R_n (S11 - A *S12.T()); 1277 1278 mlnorm<sq_T>* tmp = new mlnorm<sq_T> (); 1279 tmp->set_rv (rvn); tmp->set_rvc (rvc); 1280 tmp->set_parameters (A, mu1 - A*mu2, R_n); 1281 return tmp; 1282 } 1283 1284 //// 1285 /////// 1286 template<class sq_T> 1287 void mgnorm<sq_T >::set_parameters (fnc* g0, const sq_T &R0) {g = g0; this->iepdf.set_parameters (zeros (g->dimension()), R0);} 1288 template<class sq_T> 1289 void mgnorm<sq_T >::condition (const vec &cond) {this->iepdf._mu() = g->eval (cond);}; 1290 1291 template<class sq_T> 1292 std::ostream &operator<< (std::ostream &os, mlnorm<sq_T> &ml) 1293 { 1294 os << "A:" << ml.A << endl; 1295 os << "mu:" << ml.mu_const << endl; 1296 os << "R:" << ml._R() << endl; 1297 return os; 1298 }; 1332 1299 1333 1300 } -
library/bdm/stat/merger.h
r477 r488 178 178 //! Set support points from a pdf by drawing N samples 179 179 void set_support ( const epdf &overall, int N ) { 180 eSmp.set_statistics ( &overall, N );180 eSmp.set_statistics ( overall, N ); 181 181 Npoints = N; 182 182 } -
library/tests/testResample.cpp
r477 r488 25 25 euni eun; 26 26 eun.set_parameters ( "0", "1" ); 27 emp.set_statistics ( ones ( 10 ), &eun );27 emp.set_statistics ( ones ( 10 ), eun ); 28 28 vec &v = emp._w(); 29 29 Array<vec> &S = emp._samples(); -
library/tests/testSmp.cpp
r477 r488 86 86 cout << "======= MMix ======== " << endl; 87 87 mmix mMix; 88 Array< mpdf*> mComs ( 2 );88 Array<shared_ptr<mpdf> > mComs ( 2 ); 89 89 mComs ( 0 ) = &mG; 90 90 eN.set_mu ( vec_2 ( 0.0, 0.0 ) ); … … 94 94 95 95 Smp = mMix.samplecond_m ( mu0, N ); 96 disp ( mMix.e()->mean(), zeros ( 2 ), Smp );96 disp ( 0.5*eN.mean()+0.4*eG.mean(), zeros ( 2 ), Smp ); 97 97 98 98 cout << "======= EProd ======== " << endl; -
library/tests/test_kalman_QR.cpp
r477 r488 69 69 KF_QR.set_parameters ( &evolQR, &evolQR, 100 ); 70 70 evolQR.condition ( "1 1 1" ); 71 KF_QR.set_statistics ( evolQR.e(), &KF ); 71 egamma kfinit=egamma("10 10 10","1 1 1"); 72 KF_QR.set_statistics ( egamma("10 10 10","1 1 1"), &KF ); 72 73 const epdf& mpost = KF_QR.posterior(); 73 74 const epdf& mposttr = KFtr.posterior(); -
library/tests/test_particle.cpp
r477 r488 25 25 euni eun; 26 26 eun.set_parameters ( "0", "1" ); 27 emp.set_statistics ( ones ( 10 ), &eun );27 emp.set_statistics ( ones ( 10 ), eun ); 28 28 vec &v = emp._w(); 29 29 Array<vec> &S = emp._samples();