Changeset 477 for library/bdm/stat/emix.h
- Timestamp:
- 08/05/09 14:40:03 (15 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/stat/emix.h
r471 r477 14 14 #define EMIX_H 15 15 16 #define LOG2 0.69314718055995 16 #define LOG2 0.69314718055995 17 17 18 18 #include "../shared_ptr.h" … … 48 48 //!Default constructor. By default, the given epdf is not copied! 49 49 //! It is assumed that this function will be used only temporarily. 50 mratio ( const epdf* nom0, const RV &rv, bool copy =false ) :mpdf ( ), dl ( ) {50 mratio ( const epdf* nom0, const RV &rv, bool copy = false ) : mpdf ( ), dl ( ) { 51 51 // adjust rv and rvc 52 52 rvc = nom0->_rv().subt ( rv ); 53 53 dimc = rvc._dsize(); 54 set_ep (shared_ptr<epdf>(new epdf));55 e()->set_parameters (rv._dsize());56 e()->set_rv (rv);57 54 set_ep ( shared_ptr<epdf> ( new epdf ) ); 55 e()->set_parameters ( rv._dsize() ); 56 e()->set_rv ( rv ); 57 58 58 //prepare data structures 59 if ( copy ) {it_error ( "todo" ); destroynom=true; } 60 else { nom = nom0; destroynom = false; } 61 it_assert_debug ( rvc.length() >0,"Makes no sense to use this object!" ); 62 59 if ( copy ) { 60 it_error ( "todo" ); 61 destroynom = true; 62 } else { 63 nom = nom0; 64 destroynom = false; 65 } 66 it_assert_debug ( rvc.length() > 0, "Makes no sense to use this object!" ); 67 63 68 // build denominator 64 69 den = nom->marginal ( rvc ); 65 dl.set_connection (rv,rvc,nom0->_rv());70 dl.set_connection ( rv, rvc, nom0->_rv() ); 66 71 }; 67 72 double evallogcond ( const vec &val, const vec &cond ) { 68 73 double tmp; 69 74 vec nom_val ( e()->dimension() + dimc ); 70 dl.pushup_cond ( nom_val, val,cond );75 dl.pushup_cond ( nom_val, val, cond ); 71 76 tmp = exp ( nom->evallog ( nom_val ) - den->evallog ( cond ) ); 72 it_assert_debug ( std::isfinite ( tmp ), "Infinite value" );77 it_assert_debug ( std::isfinite ( tmp ), "Infinite value" ); 73 78 return tmp; 74 79 } 75 80 //! Object takes ownership of nom and will destroy it 76 void ownnom() {destroynom=true;} 81 void ownnom() { 82 destroynom = true; 83 } 77 84 //! Default destructor 78 ~mratio() {delete den; if ( destroynom ) {delete nom;}} 85 ~mratio() { 86 delete den; 87 if ( destroynom ) { 88 delete nom; 89 } 90 } 79 91 }; 80 92 … … 102 114 //! Set weights \c w and components \c Coms 103 115 //!By default Coms are copied inside. Parameter \c copy can be set to false if Coms live externally. Use method ownComs() if Coms should be destroyed by the destructor. 104 void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy =false );116 void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy = false ); 105 117 106 118 vec sample() const; 107 119 vec mean() const { 108 int i; vec mu = zeros ( dim ); 109 for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); } 120 int i; 121 vec mu = zeros ( dim ); 122 for ( i = 0; i < w.length(); i++ ) { 123 mu += w ( i ) * Coms ( i )->mean(); 124 } 110 125 return mu; 111 126 } … … 113 128 //non-central moment 114 129 vec mom2 = zeros ( dim ); 115 for ( int i = 0;i < w.length();i++ ) {mom2 += w ( i ) * (Coms(i)->variance() + pow ( Coms ( i )->mean(),2 )); } 130 for ( int i = 0; i < w.length(); i++ ) { 131 mom2 += w ( i ) * ( Coms ( i )->variance() + pow ( Coms ( i )->mean(), 2 ) ); 132 } 116 133 //central moment 117 return mom2 -pow ( mean(),2 );134 return mom2 - pow ( mean(), 2 ); 118 135 } 119 136 double evallog ( const vec &val ) const { 120 137 int i; 121 138 double sum = 0.0; 122 for ( i = 0;i < w.length();i++ ) {sum += w ( i ) * exp ( Coms ( i )->evallog ( val ) );} 123 if ( sum==0.0 ) {sum=std::numeric_limits<double>::epsilon();} 124 double tmp=log ( sum ); 125 it_assert_debug ( std::isfinite ( tmp ),"Infinite" ); 139 for ( i = 0; i < w.length(); i++ ) { 140 sum += w ( i ) * exp ( Coms ( i )->evallog ( val ) ); 141 } 142 if ( sum == 0.0 ) { 143 sum = std::numeric_limits<double>::epsilon(); 144 } 145 double tmp = log ( sum ); 146 it_assert_debug ( std::isfinite ( tmp ), "Infinite" ); 126 147 return tmp; 127 148 }; 128 149 vec evallog_m ( const mat &Val ) const { 129 vec x =zeros ( Val.cols() );150 vec x = zeros ( Val.cols() ); 130 151 for ( int i = 0; i < w.length(); i++ ) { 131 x += w ( i ) *exp ( Coms ( i )->evallog_m ( Val ) );152 x += w ( i ) * exp ( Coms ( i )->evallog_m ( Val ) ); 132 153 } 133 154 return log ( x ); … … 147 168 //Access methods 148 169 //! returns a pointer to the internal mean value. Use with Care! 149 vec& _w() {return w;} 150 virtual ~emix() {if ( destroyComs ) {for ( int i=0;i<Coms.length();i++ ) {delete Coms ( i );}}} 170 vec& _w() { 171 return w; 172 } 173 virtual ~emix() { 174 if ( destroyComs ) { 175 for ( int i = 0; i < Coms.length(); i++ ) { 176 delete Coms ( i ); 177 } 178 } 179 } 151 180 //! Auxiliary function for taking ownership of the Coms() 152 void ownComs() {destroyComs=true;} 181 void ownComs() { 182 destroyComs = true; 183 } 153 184 154 185 //!access function 155 epdf* _Coms ( int i ) {return Coms ( i );} 156 void set_rv(const RV &rv){ 157 epdf::set_rv(rv); 158 for(int i=0;i<Coms.length();i++){Coms(i)->set_rv(rv);} 186 epdf* _Coms ( int i ) { 187 return Coms ( i ); 188 } 189 void set_rv ( const RV &rv ) { 190 epdf::set_rv ( rv ); 191 for ( int i = 0; i < Coms.length(); i++ ) { 192 Coms ( i )->set_rv ( rv ); 193 } 159 194 } 160 195 }; … … 179 214 //! Set weights \c w and components \c Coms 180 215 //!By default Coms are copied inside. Parameter \c copy can be set to false if Coms live externally. Use method ownComs() if Coms should be destroyed by the destructor. 181 void set_parameters ( const vec &w, const Array<egiw*> &Coms, bool copy =false );216 void set_parameters ( const vec &w, const Array<egiw*> &Coms, bool copy = false ); 182 217 183 218 //!return expected value … … 188 223 189 224 //!return the expected variance 190 225 vec variance() const; 191 226 192 227 // TODO!!! Defined to follow ANSI and/or for future development 193 228 void mean_mat ( mat &M, mat&R ) const {}; 194 double evallog_nn ( const vec &val ) const {return 0;}; 195 double lognc () const {return 0;}; 229 double evallog_nn ( const vec &val ) const { 230 return 0; 231 }; 232 double lognc () const { 233 return 0; 234 }; 196 235 emix* marginal ( const RV &rv ) const; 197 236 198 237 //Access methods 199 238 //! returns a pointer to the internal mean value. Use with Care! 200 vec& _w() {return w;} 201 virtual ~egiwmix() {if ( destroyComs ) {for ( int i=0;i<Coms.length();i++ ) {delete Coms ( i );}}} 239 vec& _w() { 240 return w; 241 } 242 virtual ~egiwmix() { 243 if ( destroyComs ) { 244 for ( int i = 0; i < Coms.length(); i++ ) { 245 delete Coms ( i ); 246 } 247 } 248 } 202 249 //! Auxiliary function for taking ownership of the Coms() 203 void ownComs() {destroyComs=true;} 250 void ownComs() { 251 destroyComs = true; 252 } 204 253 205 254 //!access function 206 egiw* _Coms ( int i ) {return Coms ( i );} 207 208 void set_rv(const RV &rv){ 209 egiw::set_rv(rv); 210 for(int i=0;i<Coms.length();i++){Coms(i)->set_rv(rv);} 255 egiw* _Coms ( int i ) { 256 return Coms ( i ); 257 } 258 259 void set_rv ( const RV &rv ) { 260 egiw::set_rv ( rv ); 261 for ( int i = 0; i < Coms.length(); i++ ) { 262 Coms ( i )->set_rv ( rv ); 263 } 211 264 } 212 265 … … 236 289 /*!\brief Constructor from list of mFacs, 237 290 */ 238 mprod() :dummy(new epdf()) { }239 mprod ( Array<mpdf*> mFacs):240 dummy(new epdf()) {241 set_elements(mFacs);242 } 243 244 void set_elements (Array<mpdf*> mFacs , bool own=false) {245 246 compositepdf::set_elements (mFacs,own);247 dls.set_size (mFacs.length());248 epdfs.set_size (mFacs.length());249 250 set_ep (dummy);251 RV rv =getrv ( true );291 mprod() : dummy ( new epdf() ) { } 292 mprod ( Array<mpdf*> mFacs ) : 293 dummy ( new epdf() ) { 294 set_elements ( mFacs ); 295 } 296 297 void set_elements ( Array<mpdf*> mFacs , bool own = false ) { 298 299 compositepdf::set_elements ( mFacs, own ); 300 dls.set_size ( mFacs.length() ); 301 epdfs.set_size ( mFacs.length() ); 302 303 set_ep ( dummy ); 304 RV rv = getrv ( true ); 252 305 set_rv ( rv ); 253 dummy->set_parameters (rv._dsize());254 setrvc (e()->_rv(), rvc);306 dummy->set_parameters ( rv._dsize() ); 307 setrvc ( e()->_rv(), rvc ); 255 308 // rv and rvc established = > we can link them with mpdfs 256 for ( int i = 0; i < mpdfs.length(); i++ ) {309 for ( int i = 0; i < mpdfs.length(); i++ ) { 257 310 dls ( i ) = new datalink_m2m; 258 dls (i)->set_connection( mpdfs ( i )->_rv(), mpdfs ( i )->_rvc(), _rv(), _rvc() );259 } 260 261 for ( int i =0; i<mpdfs.length(); i++ ) {262 epdfs (i) = mpdfs(i)->e();311 dls ( i )->set_connection ( mpdfs ( i )->_rv(), mpdfs ( i )->_rvc(), _rv(), _rvc() ); 312 } 313 314 for ( int i = 0; i < mpdfs.length(); i++ ) { 315 epdfs ( i ) = mpdfs ( i )->e(); 263 316 } 264 317 }; … … 267 320 int i; 268 321 double res = 0.0; 269 for ( i = mpdfs.length() - 1; i >= 0;i-- ) {322 for ( i = mpdfs.length() - 1; i >= 0; i-- ) { 270 323 /* if ( mpdfs(i)->_rvc().count() >0) { 271 324 mpdfs ( i )->condition ( dls ( i )->get_cond ( val,cond ) ); … … 280 333 return res; 281 334 } 282 vec evallogcond_m (const mat &Dt, const vec &cond) {283 vec tmp (Dt.cols());284 for (int i=0;i<Dt.cols(); i++){285 tmp (i) = evallogcond(Dt.get_col(i),cond);286 } 287 return tmp; 288 }; 289 vec evallogcond_m (const Array<vec> &Dt, const vec &cond) {290 vec tmp (Dt.length());291 for (int i=0;i<Dt.length(); i++){292 tmp (i) = evallogcond(Dt(i),cond);293 } 294 return tmp; 335 vec evallogcond_m ( const mat &Dt, const vec &cond ) { 336 vec tmp ( Dt.cols() ); 337 for ( int i = 0; i < Dt.cols(); i++ ) { 338 tmp ( i ) = evallogcond ( Dt.get_col ( i ), cond ); 339 } 340 return tmp; 341 }; 342 vec evallogcond_m ( const Array<vec> &Dt, const vec &cond ) { 343 vec tmp ( Dt.length() ); 344 for ( int i = 0; i < Dt.length(); i++ ) { 345 tmp ( i ) = evallogcond ( Dt ( i ), cond ); 346 } 347 return tmp; 295 348 }; 296 349 … … 298 351 //TODO smarter... 299 352 vec samplecond ( const vec &cond ) { 300 301 vec smp= std::numeric_limits<double>::infinity() * ones ( e()->dimension() );353 //! Ugly hack to help to discover if mpfs are not in proper order. Correct solution = check that explicitely. 354 vec smp = std::numeric_limits<double>::infinity() * ones ( e()->dimension() ); 302 355 vec smpi; 303 356 // Hard assumption here!!! We are going backwards, to assure that samples that are needed from smp are already generated! 304 for ( int i = ( mpdfs.length() - 1 ); i >= 0;i-- ) {357 for ( int i = ( mpdfs.length() - 1 ); i >= 0; i-- ) { 305 358 if ( mpdfs ( i )->dimensionc() ) { 306 mpdfs ( i )->condition ( dls ( i )->get_cond ( smp , cond ) ); // smp is val here!!359 mpdfs ( i )->condition ( dls ( i )->get_cond ( smp , cond ) ); // smp is val here!! 307 360 } 308 361 smpi = epdfs ( i )->sample(); … … 314 367 } 315 368 mat samplecond ( const vec &cond, int N ) { 316 mat Smp ( dimension(),N ); 317 for ( int i=0;i<N;i++ ) {Smp.set_col ( i,samplecond ( cond ) );} 369 mat Smp ( dimension(), N ); 370 for ( int i = 0; i < N; i++ ) { 371 Smp.set_col ( i, samplecond ( cond ) ); 372 } 318 373 return Smp; 319 374 } … … 327 382 //! \endcode 328 383 //!@} 329 void from_setting (const Setting &set){384 void from_setting ( const Setting &set ) { 330 385 Array<mpdf*> Atmp; //temporary Array 331 UI::get (Atmp,set, "mpdfs", UI::compulsory);332 set_elements (Atmp,true);333 } 334 386 UI::get ( Atmp, set, "mpdfs", UI::compulsory ); 387 set_elements ( Atmp, true ); 388 } 389 335 390 }; 336 UIREGISTER (mprod);391 UIREGISTER ( mprod ); 337 392 338 393 //! Product of independent epdfs. For dependent pdfs, use mprod. … … 344 399 Array<datalink*> dls; 345 400 public: 346 eprod () : epdfs ( 0 ), dls ( 0 ) {};347 void set_parameters ( const Array<const epdf*> &epdfs0, bool named =true ) {348 epdfs =epdfs0;//.set_length ( epdfs0.length() );401 eprod () : epdfs ( 0 ), dls ( 0 ) {}; 402 void set_parameters ( const Array<const epdf*> &epdfs0, bool named = true ) { 403 epdfs = epdfs0;//.set_length ( epdfs0.length() ); 349 404 dls.set_length ( epdfs.length() ); 350 405 351 bool independent =true;406 bool independent = true; 352 407 if ( named ) { 353 for ( int i =0;i<epdfs.length();i++ ) {354 independent =rv.add ( epdfs ( i )->_rv() );355 it_assert_debug ( independent ==true, "eprod:: given components are not independent." );408 for ( int i = 0; i < epdfs.length(); i++ ) { 409 independent = rv.add ( epdfs ( i )->_rv() ); 410 it_assert_debug ( independent == true, "eprod:: given components are not independent." ); 356 411 } 357 dim =rv._dsize();358 } 359 else {360 dim =0; for ( int i=0;i<epdfs.length();i++ ) {361 dim +=epdfs ( i )->dimension();412 dim = rv._dsize(); 413 } else { 414 dim = 0; 415 for ( int i = 0; i < epdfs.length(); i++ ) { 416 dim += epdfs ( i )->dimension(); 362 417 } 363 418 } 364 419 // 365 int cumdim =0;366 int dimi =0;420 int cumdim = 0; 421 int dimi = 0; 367 422 int i; 368 for ( i =0;i<epdfs.length();i++ ) {423 for ( i = 0; i < epdfs.length(); i++ ) { 369 424 dls ( i ) = new datalink; 370 if ( named ) {dls ( i )->set_connection ( epdfs ( i )->_rv() , rv );} 371 else { 425 if ( named ) { 426 dls ( i )->set_connection ( epdfs ( i )->_rv() , rv ); 427 } else { 372 428 dimi = epdfs ( i )->dimension(); 373 dls ( i )->set_connection ( dimi, dim, linspace ( cumdim, cumdim+dimi-1 ) );374 cumdim +=dimi;429 dls ( i )->set_connection ( dimi, dim, linspace ( cumdim, cumdim + dimi - 1 ) ); 430 cumdim += dimi; 375 431 } 376 432 } … … 379 435 vec mean() const { 380 436 vec tmp ( dim ); 381 for ( int i =0;i<epdfs.length();i++ ) {437 for ( int i = 0; i < epdfs.length(); i++ ) { 382 438 vec pom = epdfs ( i )->mean(); 383 439 dls ( i )->pushup ( tmp, pom ); … … 387 443 vec variance() const { 388 444 vec tmp ( dim ); //second moment 389 for ( int i =0;i<epdfs.length();i++ ) {445 for ( int i = 0; i < epdfs.length(); i++ ) { 390 446 vec pom = epdfs ( i )->mean(); 391 dls ( i )->pushup ( tmp, pow ( pom, 2 ) );392 } 393 return tmp -pow ( mean(),2 );447 dls ( i )->pushup ( tmp, pow ( pom, 2 ) ); 448 } 449 return tmp - pow ( mean(), 2 ); 394 450 } 395 451 vec sample() const { 396 452 vec tmp ( dim ); 397 for ( int i =0;i<epdfs.length();i++ ) {453 for ( int i = 0; i < epdfs.length(); i++ ) { 398 454 vec pom = epdfs ( i )->sample(); 399 455 dls ( i )->pushup ( tmp, pom ); … … 402 458 } 403 459 double evallog ( const vec &val ) const { 404 double tmp =0;405 for ( int i =0;i<epdfs.length();i++ ) {406 tmp +=epdfs ( i )->evallog ( dls ( i )->pushdown ( val ) );407 } 408 it_assert_debug ( std::isfinite ( tmp ), "Infinite" );460 double tmp = 0; 461 for ( int i = 0; i < epdfs.length(); i++ ) { 462 tmp += epdfs ( i )->evallog ( dls ( i )->pushdown ( val ) ); 463 } 464 it_assert_debug ( std::isfinite ( tmp ), "Infinite" ); 409 465 return tmp; 410 466 } 411 467 //!access function 412 const epdf* operator () ( int i ) const {it_assert_debug ( i<epdfs.length(),"wrong index" );return epdfs ( i );} 468 const epdf* operator () ( int i ) const { 469 it_assert_debug ( i < epdfs.length(), "wrong index" ); 470 return epdfs ( i ); 471 } 413 472 414 473 //!Destructor 415 ~eprod() {for ( int i=0;i<epdfs.length();i++ ) {delete dls ( i );}} 474 ~eprod() { 475 for ( int i = 0; i < epdfs.length(); i++ ) { 476 delete dls ( i ); 477 } 478 } 416 479 }; 417 480 … … 430 493 public: 431 494 //!Default constructor 432 mmix() :iepdf(new emix()) {433 set_ep(iepdf);495 mmix() : iepdf ( new emix() ) { 496 set_ep ( iepdf ); 434 497 } 435 498 … … 438 501 Array<epdf*> Eps ( Coms.length() ); 439 502 440 for ( int i = 0; i < Coms.length();i++ ) {441 Eps (i) = Coms(i)->e();442 } 443 444 iepdf->set_parameters (w, Eps);503 for ( int i = 0; i < Coms.length(); i++ ) { 504 Eps ( i ) = Coms ( i )->e(); 505 } 506 507 iepdf->set_parameters ( w, Eps ); 445 508 } 446 509 447 510 void condition ( const vec &cond ) { 448 for ( int i = 0;i < Coms.length();i++ ) {Coms ( i )->condition ( cond );} 511 for ( int i = 0; i < Coms.length(); i++ ) { 512 Coms ( i )->condition ( cond ); 513 } 449 514 }; 450 515 };