Changeset 886
- Timestamp:
- 03/29/10 23:01:49 (15 years ago)
- Location:
- library
- Files:
-
- 7 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/estim/mixtures.cpp
r780 r886 35 35 } 36 36 37 //est already exists - must be deleted before build_est() can be used38 delete est;39 build_est();40 37 } 41 38 -
library/bdm/estim/mixtures.h
r766 r886 48 48 //! Statistics for weights 49 49 multiBM weights; 50 //aux 51 friend class eprod_mix; 50 52 //!Posterior on component parameters 51 eprod* est; 53 class eprod_mix: public eprod_base { 54 protected: 55 const MixEF &mix; // pointer to parent.n 56 public: 57 eprod_mix(const MixEF &m):mix(m){} 58 const epdf* factor(int i) const {return (i==(mix.n-1)) ? &mix.weights.posterior() : &mix.Coms(i)->posterior();} 59 const int no_factors()const {return mix.n+1;} 60 } est; 52 61 ////!Indeces of component rvc in common rvc 53 62 … … 55 64 MixEF_METHOD method; 56 65 57 //! Auxiliary function for use in constructors58 void build_est() {59 est = new eprod;60 if ( n > 0 ) {61 Array<const epdf*> epdfs ( n + 1 );62 for ( int i = 0; i < Coms.length(); i++ ) {63 epdfs ( i ) = & ( Coms ( i )->posterior() );64 }65 // last in the product is the weight66 epdfs ( n ) = & ( weights.posterior() );67 est->set_parameters ( epdfs, false );68 }69 }70 71 66 public: 72 67 //! Full constructor 73 68 MixEF ( const Array<BMEF*> &Coms0, const vec &alpha0 ) : 74 69 BMEF ( ), n ( Coms0.length() ), Coms ( n ), 75 weights (), method ( QB ) {70 weights (), est(*this), method ( QB ) { 76 71 for ( int i = 0; i < n; i++ ) { 77 72 Coms ( i ) = ( BMEF* ) Coms0 ( i )->_copy(); … … 79 74 weights.set_parameters(alpha0); 80 75 weights.validate(); 81 build_est();82 76 } 83 77 … … 85 79 MixEF () : 86 80 BMEF ( ), n ( 0 ), Coms ( 0 ), 87 weights (), method ( QB ) { 88 build_est(); 81 weights (), est(*this), method ( QB ) { 89 82 } 90 83 //! Copy constructor 91 84 MixEF ( const MixEF &M2 ) : BMEF ( ), n ( M2.n ), Coms ( n ), 92 weights ( M2.weights ), method ( M2.method ) {85 weights ( M2.weights ), est(*this), method ( M2.method ) { 93 86 for ( int i = 0; i < n; i++ ) { 94 87 Coms ( i ) = (BMEF*) M2.Coms ( i )->_copy(); 95 88 } 96 build_est();97 89 } 98 90 … … 103 95 void init ( BMEF* Com0, const mat &Data, const int c = 5 ); 104 96 //Destructor 105 ~MixEF() {106 delete est;107 for ( int i = 0; i < n; i++ ) {108 delete Coms ( i );109 }110 }111 97 //! Recursive EM-like algorithm (QB-variant), see Karny et. al, 2006 112 98 void bayes ( const vec &yt, const vec &cond ); … … 117 103 double logpred ( const vec &yt ) const; 118 104 //! return correctly typed posterior (covariant return) 119 const eprod & posterior() const {120 return *est;105 const eprod_mix& posterior() const { 106 return est; 121 107 } 122 108 -
library/bdm/stat/emix.cpp
r878 r886 3 3 namespace bdm { 4 4 5 void emix ::validate (){6 bdm_assert ( Coms.length() > 0, "There has to be at least one component." );7 8 bdm_assert ( Coms.length() == w.length(), "It is obligatory to define weights of all the components." );5 void emix_base::validate (){ 6 bdm_assert ( no_coms() > 0, "There has to be at least one component." ); 7 8 bdm_assert ( no_coms() == w.length(), "It is obligatory to define weights of all the components." ); 9 9 10 10 double sum_w = sum ( w ); … … 12 12 w = w / sum_w; 13 13 14 dim = Coms( 0 )->dimension();15 RV rv_tmp = Coms( 0 )->_rv() ;16 bool isnamed = Coms( 0 )->isnamed();17 for ( int i = 1; i < Coms.length(); i++ ) {18 bdm_assert ( dim == ( Coms( i )->dimension() ), "Component sizes do not match!" );19 isnamed &= Coms(i)->isnamed() & Coms(i)->_rv().equal(rv_tmp);14 dim = component ( 0 )->dimension(); 15 RV rv_tmp = component ( 0 )->_rv() ; 16 bool isnamed = component( 0 )->isnamed(); 17 for ( int i = 1; i < no_coms(); i++ ) { 18 bdm_assert ( dim == ( component ( i )->dimension() ), "Component sizes do not match!" ); 19 isnamed &= component(i)->isnamed() & component(i)->_rv().equal(rv_tmp); 20 20 } 21 21 if (isnamed) … … 23 23 } 24 24 25 void emix::from_setting ( const Setting &set ) { 26 UI::get ( Coms, set, "pdfs", UI::compulsory ); 27 28 if ( !UI::get ( w, set, "weights", UI::optional ) ) { 29 int len = Coms.length(); 30 w.set_length ( len ); 31 w = 1.0 / len; 32 } 33 } 34 35 36 vec emix::sample() const { 25 26 27 vec emix_base::sample() const { 37 28 //Sample which component 38 29 vec cumDist = cumsum ( w ); … … 46 37 } 47 38 48 return Coms( i )->sample();49 } 50 51 vec emix ::mean() const {39 return component ( i )->sample(); 40 } 41 42 vec emix_base::mean() const { 52 43 int i; 53 44 vec mu = zeros ( dim ); 54 45 for ( i = 0; i < w.length(); i++ ) { 55 mu += w ( i ) * Coms( i )->mean();46 mu += w ( i ) * component ( i )->mean(); 56 47 } 57 48 return mu; 58 49 } 59 50 60 vec emix ::variance() const {51 vec emix_base::variance() const { 61 52 //non-central moment 62 53 vec mom2 = zeros ( dim ); 63 54 for ( int i = 0; i < w.length(); i++ ) { 64 mom2 += w ( i ) * ( Coms ( i )->variance() + pow ( Coms( i )->mean(), 2 ) );55 mom2 += w ( i ) * ( component( i )->variance() + pow ( component ( i )->mean(), 2 ) ); 65 56 } 66 57 //central moment … … 68 59 } 69 60 70 double emix ::evallog ( const vec &val ) const {61 double emix_base::evallog ( const vec &val ) const { 71 62 int i; 72 63 double sum = 0.0; 73 64 for ( i = 0; i < w.length(); i++ ) { 74 sum += w ( i ) * exp ( Coms( i )->evallog ( val ) );65 sum += w ( i ) * exp ( component ( i )->evallog ( val ) ); 75 66 } 76 67 if ( sum == 0.0 ) { … … 82 73 } 83 74 84 vec emix ::evallog_mat ( const mat &Val ) const {75 vec emix_base::evallog_mat ( const mat &Val ) const { 85 76 vec x = zeros ( Val.cols() ); 86 77 for ( int i = 0; i < w.length(); i++ ) { 87 x += w ( i ) * exp ( Coms( i )->evallog_mat ( Val ) );78 x += w ( i ) * exp ( component( i )->evallog_mat ( Val ) ); 88 79 } 89 80 return log ( x ); 90 81 }; 91 82 92 mat emix ::evallog_coms ( const mat &Val ) const {83 mat emix_base::evallog_coms ( const mat &Val ) const { 93 84 mat X ( w.length(), Val.cols() ); 94 85 for ( int i = 0; i < w.length(); i++ ) { 95 X.set_row ( i, w ( i ) *exp ( Coms( i )->evallog_mat ( Val ) ) );86 X.set_row ( i, w ( i ) *exp ( component( i )->evallog_mat ( Val ) ) ); 96 87 } 97 88 return X; 98 89 } 99 90 100 shared_ptr<epdf> emix ::marginal ( const RV &rv ) const {91 shared_ptr<epdf> emix_base::marginal ( const RV &rv ) const { 101 92 emix *tmp = new emix(); 102 93 shared_ptr<epdf> narrow ( tmp ); … … 105 96 } 106 97 107 void emix ::marginal ( const RV &rv, emix &target ) const {98 void emix_base::marginal ( const RV &rv, emix &target ) const { 108 99 bdm_assert ( isnamed(), "rvs are not assigned" ); 109 100 110 Array<shared_ptr<epdf> > Cn ( Coms.length() );111 for ( int i = 0; i < Coms.length(); i++ ) {112 Cn ( i ) = Coms( i )->marginal ( rv );101 Array<shared_ptr<epdf> > Cn ( no_coms() ); 102 for ( int i = 0; i < no_coms(); i++ ) { 103 Cn ( i ) = component ( i )->marginal ( rv ); 113 104 } 114 105 … … 118 109 } 119 110 120 shared_ptr<pdf> emix ::condition ( const RV &rv ) const {111 shared_ptr<pdf> emix_base::condition ( const RV &rv ) const { 121 112 bdm_assert ( isnamed(), "rvs are not assigned" ); 122 113 mratio *tmp = new mratio ( this, rv ); … … 124 115 } 125 116 126 void egiwmix::set_parameters ( const vec &w0, const Array<egiw*> &Coms0, bool copy ) { 127 w = w0 / sum ( w0 ); 128 int i; 129 for ( i = 0; i < w.length(); i++ ) { 130 bdm_assert_debug ( dim == ( Coms0 ( i )->dimension() ), "Component sizes do not match!" ); 131 } 132 if ( copy ) { 133 Coms.set_length ( Coms0.length() ); 134 for ( i = 0; i < w.length(); i++ ) { 135 bdm_error ( "Not implemented" ); 136 // *Coms ( i ) = *Coms0 ( i ); 137 } 138 destroyComs = true; 139 } else { 140 Coms = Coms0; 141 destroyComs = false; 142 } 143 } 144 145 void egiwmix::validate (){ 146 dim = Coms ( 0 )->dimension(); 147 } 148 149 vec egiwmix::sample() const { 150 //Sample which component 151 vec cumDist = cumsum ( w ); 152 double u0; 153 #pragma omp critical 154 u0 = UniRNG.sample(); 155 156 int i = 0; 157 while ( ( cumDist ( i ) < u0 ) && ( i < ( w.length() - 1 ) ) ) { 158 i++; 159 } 160 161 return Coms ( i )->sample(); 162 } 163 164 vec egiwmix::mean() const { 165 int i; 166 vec mu = zeros ( dim ); 167 for ( i = 0; i < w.length(); i++ ) { 168 mu += w ( i ) * Coms ( i )->mean(); 169 } 170 return mu; 171 } 172 173 vec egiwmix::variance() const { 174 // non-central moment 175 vec mom2 = zeros ( dim ); 176 for ( int i = 0; i < w.length(); i++ ) { 177 // pow is overloaded, we have to use another approach 178 mom2 += w ( i ) * ( Coms ( i )->variance() + elem_mult ( Coms ( i )->mean(), Coms ( i )->mean() ) ); 179 } 180 // central moment 181 // pow is overloaded, we have to use another approach 182 return mom2 - elem_mult ( mean(), mean() ); 183 } 184 185 shared_ptr<epdf> egiwmix::marginal ( const RV &rv ) const { 186 emix *tmp = new emix(); 187 shared_ptr<epdf> narrow ( tmp ); 188 marginal ( rv, *tmp ); 189 return narrow; 190 } 191 192 void egiwmix::marginal ( const RV &rv, emix &target ) const { 193 bdm_assert_debug ( isnamed(), "rvs are not assigned" ); 194 195 Array<shared_ptr<epdf> > Cn ( Coms.length() ); 196 for ( int i = 0; i < Coms.length(); i++ ) { 197 Cn ( i ) = Coms ( i )->marginal ( rv ); 198 } 199 200 target._w() = w; 201 target._Coms() = Cn; 202 target.validate(); 203 } 204 205 egiw* egiwmix::approx() { 206 // NB: dimx == 1 !!! 207 // The following code might look a bit spaghetti-like, 208 // consult Dedecius, K. et al.: Partial forgetting in AR models. 209 210 double sumVecCommon; // common part for many terms in eq. 211 int len = w.length(); // no. of mix components 212 int dimLS = Coms ( 1 )->_V()._D().length() - 1; // dim of LS 213 vec vecNu ( len ); // vector of dfms of components 214 vec vecD ( len ); // vector of LS reminders of comps. 215 vec vecCommon ( len ); // vector of common parts 216 mat matVecsTheta; // matrix which rows are theta vects. 217 218 // fill in the vectors vecNu, vecD and matVecsTheta 219 for ( int i = 0; i < len; i++ ) { 220 vecNu.shift_left ( Coms ( i )->_nu() ); 221 vecD.shift_left ( Coms ( i )->_V()._D() ( 0 ) ); 222 matVecsTheta.append_row ( Coms ( i )->est_theta() ); 223 } 224 225 // calculate the common parts and their sum 226 vecCommon = elem_mult ( w, elem_div ( vecNu, vecD ) ); 227 sumVecCommon = sum ( vecCommon ); 228 229 // LS estimator of theta 230 vec aprEstTheta ( dimLS ); 231 aprEstTheta.zeros(); 232 for ( int i = 0; i < len; i++ ) { 233 aprEstTheta += matVecsTheta.get_row ( i ) * vecCommon ( i ); 234 } 235 aprEstTheta /= sumVecCommon; 236 237 238 // LS estimator of dfm 239 double aprNu; 240 double A = log ( sumVecCommon ); // Term 'A' in equation 241 242 for ( int i = 0; i < len; i++ ) { 243 A += w ( i ) * ( log ( vecD ( i ) ) - psi ( 0.5 * vecNu ( i ) ) ); 244 } 245 246 aprNu = ( 1 + sqrt ( 1 + 2 * ( A - LOG2 ) / 3 ) ) / ( 2 * ( A - LOG2 ) ); 247 248 249 // LS reminder (term D(0,0) in C-syntax) 250 double aprD = aprNu / sumVecCommon; 251 252 // Aproximation of cov 253 // the following code is very numerically sensitive, thus 254 // we have to eliminate decompositions etc. as much as possible 255 mat aprC = zeros ( dimLS, dimLS ); 256 for ( int i = 0; i < len; i++ ) { 257 aprC += Coms ( i )->est_theta_cov().to_mat() * w ( i ); 258 vec tmp = ( matVecsTheta.get_row ( i ) - aprEstTheta ); 259 aprC += vecCommon ( i ) * outer_product ( tmp, tmp ); 260 } 261 262 // Construct GiW pdf :: BEGIN 263 ldmat aprCinv ( inv ( aprC ) ); 264 vec D = concat ( aprD, aprCinv._D() ); 265 mat L = eye ( dimLS + 1 ); 266 L.set_submatrix ( 1, 0, aprCinv._L() * aprEstTheta ); 267 L.set_submatrix ( 1, 1, aprCinv._L() ); 268 ldmat aprLD ( L, D ); 269 270 egiw* aprgiw = new egiw ( 1, aprLD, aprNu ); 271 return aprgiw; 272 }; 117 void emix::from_setting ( const Setting &set ) { 118 UI::get ( Coms, set, "pdfs", UI::compulsory ); 119 UI::get ( w, set, "weights", UI::compulsory ); 120 } 121 122 void emix::validate (){ 123 emix_base::validate(); 124 dim = Coms ( 0 )->dimension(); 125 } 126 273 127 274 128 double mprod::evallogcond ( const vec &val, const vec &cond ) { … … 378 232 } 379 233 380 vec eprod ::mean() const {234 vec eprod_base::mean() const { 381 235 vec tmp ( dim ); 382 for ( int i = 0; i < epdfs.length(); i++ ) {383 vec pom = epdfs( i )->mean();236 for ( int i = 0; i < no_factors(); i++ ) { 237 vec pom = factor( i )->mean(); 384 238 dls ( i )->pushup ( tmp, pom ); 385 239 } … … 387 241 } 388 242 389 vec eprod ::variance() const {243 vec eprod_base::variance() const { 390 244 vec tmp ( dim ); //second moment 391 for ( int i = 0; i < epdfs.length(); i++ ) {392 vec pom = epdfs( i )->mean();245 for ( int i = 0; i < no_factors(); i++ ) { 246 vec pom = factor ( i )->mean(); 393 247 dls ( i )->pushup ( tmp, pow ( pom, 2 ) ); 394 248 } 395 249 return tmp - pow ( mean(), 2 ); 396 250 } 397 vec eprod ::sample() const {251 vec eprod_base::sample() const { 398 252 vec tmp ( dim ); 399 for ( int i = 0; i < epdfs.length(); i++ ) {400 vec pom = epdfs( i )->sample();253 for ( int i = 0; i < no_factors(); i++ ) { 254 vec pom = factor ( i )->sample(); 401 255 dls ( i )->pushup ( tmp, pom ); 402 256 } 403 257 return tmp; 404 258 } 405 double eprod ::evallog ( const vec &val ) const {259 double eprod_base::evallog ( const vec &val ) const { 406 260 double tmp = 0; 407 for ( int i = 0; i < epdfs.length(); i++ ) { 408 tmp += epdfs ( i )->evallog ( dls ( i )->pushdown ( val ) ); 409 } 410 bdm_assert_debug ( std::isfinite ( tmp ), "Infinite" ); 411 return tmp; 412 } 413 414 } 415 // mprod::mprod ( Array<pdf*> mFacs, bool overlap) : pdf ( RV(), RV() ), n ( mFacs.length() ), epdfs ( n ), pdfs ( mFacs ), rvinds ( n ), rvcinrv ( n ), irvcs_rvc ( n ) { 416 // int i; 417 // bool rvaddok; 418 // // Create rv 419 // for ( i = 0;i < n;i++ ) { 420 // rvaddok=rv.add ( pdfs ( i )->_rv() ); //add rv to common rvs. 421 // // If rvaddok==false, pdfs overlap => assert error. 422 // epdfs ( i ) = & ( pdfs ( i )->posterior() ); // add pointer to epdf 423 // }; 424 // // Create rvc 425 // for ( i = 0;i < n;i++ ) { 426 // rvc.add ( pdfs ( i )->_rvc().subt ( rv ) ); //add rv to common rvs. 427 // }; 428 // 429 // // independent = true; 430 // //test rvc of pdfs and fill rvinds 431 // for ( i = 0;i < n;i++ ) { 432 // // find ith rv in common rv 433 // rvsinrv ( i ) = pdfs ( i )->_rv().dataind ( rv ); 434 // // find ith rvc in common rv 435 // rvcinrv ( i ) = pdfs ( i )->_rvc().dataind ( rv ); 436 // // find ith rvc in common rv 437 // irvcs_rvc ( i ) = pdfs ( i )->_rvc().dataind ( rvc ); 438 // // 439 // /* if ( rvcinrv ( i ).length() >0 ) {independent = false;} 440 // if ( irvcs_rvc ( i ).length() >0 ) {independent = false;}*/ 441 // } 442 // }; 443 261 for ( int i = 0; i < no_factors(); i++ ) { 262 tmp += factor ( i )->evallog ( dls ( i )->pushdown ( val ) ); 263 } 264 //bdm_assert_debug ( std::isfinite ( tmp ), "Infinite" ); 265 return tmp; 266 } 267 268 } 269 -
library/bdm/stat/emix.h
r878 r886 97 97 98 98 99 100 101 99 private: 102 100 // not implemented 103 101 mratio ( const mratio & ); 104 102 mratio &operator= ( const mratio & ); 103 }; 104 105 class emix; //forward 106 107 /*! Base class (Interface) for mixtures 108 */ 109 class emix_base : public epdf { 110 protected: 111 //! reference to vector of weights 112 vec &w; 113 //! function returning ith component 114 virtual const epdf * component(const int &i) const=0; 115 116 virtual int no_coms() const=0; 117 118 public: 119 120 emix_base(vec &w0): w(w0){} 121 122 void validate (); 123 124 vec sample() const; 125 126 vec mean() const; 127 128 vec variance() const; 129 130 double evallog ( const vec &val ) const; 131 132 vec evallog_mat ( const mat &Val ) const; 133 134 //! Auxiliary function that returns pdflog for each component 135 mat evallog_coms ( const mat &Val ) const; 136 137 shared_ptr<epdf> marginal ( const RV &rv ) const; 138 //! Update already existing marginal density \c target 139 void marginal ( const RV &rv, emix &target ) const; 140 shared_ptr<pdf> condition ( const RV &rv ) const; 141 142 //Access methods 143 //! returns a reference to the internal weights. Use with Care! 144 vec& _w() { 145 return w; 146 } 147 148 const vec& _w() const { 149 return w; 150 } 151 //!access 152 const epdf* _com(int i) const {return component(i);} 153 105 154 }; 106 155 … … 115 164 116 165 */ 117 class emix : public e pdf{166 class emix : public emix_base { 118 167 protected: 119 168 //! weights of the components 120 vec w ;169 vec weights; 121 170 122 171 //! Component (epdfs) … … 125 174 public: 126 175 //! Default constructor 127 emix ( ) : epdf ( ) { } 128 129 virtual void validate (); 130 131 vec sample() const; 132 133 vec mean() const; 134 135 vec variance() const; 136 137 double evallog ( const vec &val ) const; 138 139 vec evallog_mat ( const mat &Val ) const; 140 141 //! Auxiliary function that returns pdflog for each component 142 mat evallog_coms ( const mat &Val ) const; 143 144 shared_ptr<epdf> marginal ( const RV &rv ) const; 145 //! Update already existing marginal density \c target 146 void marginal ( const RV &rv, emix &target ) const; 147 shared_ptr<pdf> condition ( const RV &rv ) const; 148 149 //Access methods 150 //! returns a reference to the internal weights. Use with Care! 151 vec& _w() { 152 return w; 153 } 154 155 /*! 156 \brief returns a reference to the internal array of components. Use with Care! Set components \c Coms 157 158 Shared pointers in Coms are kept inside this instance and 159 shouldn't be modified after being passed to this method. 160 */ 161 Array<shared_ptr<epdf> >& _Coms ( ) { 162 return Coms; 163 } 164 165 //! returns a reference to the internal components specified by index i. Use with Care! 166 shared_ptr<epdf> _Coms ( int i ) { 167 return Coms ( i ); 168 } 169 170 void set_rv ( const RV &rv ) { 171 epdf::set_rv ( rv ); 172 for ( int i = 0; i < Coms.length(); i++ ) { 173 Coms ( i )->set_rv ( rv ); 174 } 175 } 176 emix ( ) : emix_base ( weights) { } 177 178 const epdf* component(const int &i) const {return Coms(i).get();} 179 void validate(); 180 181 182 int no_coms() const {return Coms.length(); } 176 183 177 184 //! Load from structure with elements: … … 184 191 //!@} 185 192 void from_setting ( const Setting &set ); 193 194 void set_rv ( const RV &rv ) { 195 epdf::set_rv ( rv ); 196 for ( int i = 0; i < no_coms(); i++ ) { 197 Coms( i )->set_rv ( rv ); 198 } 199 } 200 201 Array<shared_ptr<epdf> >& _Coms ( ) { 202 return Coms; 203 } 186 204 }; 187 205 SHAREDPTR ( emix ); 188 206 UIREGISTER ( emix ); 189 207 190 /*!191 * \brief Mixture of egiws192 193 */194 class egiwmix : public egiw {195 protected:196 //! weights of the components197 vec w;198 //! Component (epdfs)199 Array<egiw*> Coms;200 //!Flag if owning Coms201 bool destroyComs;202 public:203 //!Default constructor204 egiwmix ( ) : egiw ( ) {};205 206 //! Set weights \c w and components \c Coms207 //!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.208 void set_parameters ( const vec &w, const Array<egiw*> &Coms, bool copy = false );209 210 //!return expected value211 void validate();212 213 vec mean() const;214 215 //!return a sample from the density216 vec sample() const;217 218 //!return the expected variance219 vec variance() const;220 221 // TODO!!! Defined to follow ANSI and/or for future development222 void mean_mat ( mat &M, mat&R ) const {};223 double evallog_nn ( const vec &val ) const {224 return 0;225 };226 double lognc () const {227 return 0;228 }229 230 shared_ptr<epdf> marginal ( const RV &rv ) const;231 //! marginal density update232 void marginal ( const RV &rv, emix &target ) const;233 234 //Access methods235 //! returns a pointer to the internal mean value. Use with Care!236 vec& _w() {237 return w;238 }239 virtual ~egiwmix() {240 if ( destroyComs ) {241 for ( int i = 0; i < Coms.length(); i++ ) {242 delete Coms ( i );243 }244 }245 }246 //! Auxiliary function for taking ownership of the Coms()247 void ownComs() {248 destroyComs = true;249 }250 251 //!access function252 egiw* _Coms ( int i ) {253 return Coms ( i );254 }255 256 void set_rv ( const RV &rv ) {257 egiw::set_rv ( rv );258 for ( int i = 0; i < Coms.length(); i++ ) {259 Coms ( i )->set_rv ( rv );260 }261 }262 263 //! Approximation of a GiW mix by a single GiW pdf264 egiw* approx();265 };266 208 267 209 /*! \brief Chain rule decomposition of epdf … … 329 271 SHAREDPTR ( mprod ); 330 272 273 331 274 //! Product of independent epdfs. For dependent pdfs, use mprod. 332 class eprod : public epdf {275 class eprod_base: public epdf { 333 276 protected: 334 //! Components (epdfs)335 Array<const epdf*> epdfs;336 277 //! Array of indeces 337 278 Array<datalink*> dls; 279 //! interface for a factor 280 virtual const epdf* factor(int i) const NOT_IMPLEMENTED(NULL); 281 //!number of factors 282 virtual const int no_factors() const =0; 338 283 public: 339 284 //! Default constructor 340 eprod () : epdfs ( 0 ), dls ( 0) {};285 eprod_base () : dls (0) {}; 341 286 //! Set internal 342 void set_parameters ( const Array<const epdf*> &epdfs0, bool named = true ) { 343 epdfs = epdfs0;//.set_length ( epdfs0.length() ); 344 dls.set_length ( epdfs.length() ); 287 vec mean() const; 288 289 vec variance() const; 290 291 vec sample() const; 292 293 double evallog ( const vec &val ) const; 294 295 //!Destructor 296 ~eprod_base() { 297 for ( int i = 0; i < dls.length(); i++ ) { 298 delete dls ( i ); 299 } 300 } 301 void validate() { 302 dls.set_length ( no_factors() ); 303 345 304 bool independent = true; 346 if ( named ) { 347 for ( int i = 0; i < epdfs.length(); i++ ) { 348 independent = rv.add ( epdfs ( i )->_rv() ); 349 bdm_assert_debug ( independent, "eprod:: given components are not independent." ); 350 } 351 dim = rv._dsize(); 352 353 } else { 354 dim = 0; 355 for ( int i = 0; i < epdfs.length(); i++ ) { 356 dim += epdfs ( i )->dimension(); 357 } 358 } 305 dim = 0; 306 for ( int i = 0; i < no_factors(); i++ ) { 307 independent = rv.add ( factor ( i )->_rv() ); 308 dim += factor ( i )->dimension(); 309 bdm_assert_debug ( independent, "eprod:: given components are not independent." ); 310 }; 311 359 312 // 360 313 int cumdim = 0; 361 314 int dimi = 0; 362 315 int i; 363 for ( i = 0; i < epdfs.length(); i++ ) {316 for ( i = 0; i < no_factors(); i++ ) { 364 317 dls ( i ) = new datalink; 365 if ( named ) {366 dls ( i )->set_connection ( epdfs( i )->_rv() , rv );367 } else { 368 dimi = epdfs( i )->dimension();318 if ( isnamed() ) { // rvs are complete 319 dls ( i )->set_connection ( factor ( i )->_rv() , rv ); 320 } else { //rvs are not reliable 321 dimi = factor ( i )->dimension(); 369 322 dls ( i )->set_connection ( dimi, dim, linspace ( cumdim, cumdim + dimi - 1 ) ); 370 323 cumdim += dimi; … … 373 326 374 327 } 375 376 377 vec mean() const; 378 379 vec variance() const;380 381 vec sample() const;382 383 double evallog ( const vec &val ) const;384 385 //!access function386 const epdf* operator () ( int i ) const { 387 bdm_assert_debug ( i < epdfs.length(), "wrong index" ); 388 return epdfs ( i ); 389 } 390 391 //!Destructor392 ~eprod() {393 for ( int i = 0; i < epdfs.length(); i++ ) {394 delete dls ( i );395 }396 }397 }; 398 328 }; 329 330 class eprod: public eprod_base{ 331 protected: 332 Array<shared_ptr<epdf> > factors; 333 public: 334 const epdf* factor(int i) const {return factors(i).get();} 335 const int no_factors() const {return factors.length();} 336 void set_parameters ( const Array<shared_ptr<epdf> > &epdfs0) { 337 factors = epdfs0; 338 } 339 }; 340 341 //! similar to eprod but used only internally -- factors are external pointers 342 class eprod_internal: public eprod_base{ 343 protected: 344 Array<epdf* > factors; 345 const epdf* factor(int i) const {return factors(i);} 346 const int no_factors() const {return factors.length();} 347 public: 348 void set_parameters ( const Array<epdf *> &epdfs0) { 349 factors = epdfs0; 350 } 351 }; 399 352 400 353 /*! \brief Mixture of pdfs with constant weights, all pdfs are of equal RV and RVC -
library/tests/stresssuite/merger_2d_stress.cpp
r721 r886 67 67 it << Name ( "S1" ) << f1->evallog_mat ( Grid ); 68 68 it << Name ( "S2" ) << f2->evallog_mat ( Grid ); 69 cout << ( ( enorm<ldmat>* ) ( MP->_Coms ( 0 ).get() ) )->_R().to_mat() << endl;69 // cout << ( ( enorm<ldmat>* ) ( MP->_Coms ( 0 ).get() ) )->_R().to_mat() << endl; 70 70 } -
library/tests/stresssuite/mixtures_stress.cpp
r766 r886 15 15 mat Var ( 2, 2 ), M ( 1, 2 ); 16 16 for ( i = 0; i < ep._rv().length() - 1; i++ ) { // -1 => last one is the weight 17 ( ( egiw* ) ep ( i ) )->mean_mat ( M, Var );17 ( ( egiw* ) ep.factor ( i ) )->mean_mat ( M, Var ); 18 18 cout << "Mean: " << M << endl << "Variance: " << endl << Var << endl; 19 19 } 20 cout << "Weights: " << ep ( i )->mean() << endl;20 cout << "Weights: " << ep.factor ( i )->mean() << endl; 21 21 } 22 22 -
library/tests/testsuite/epdf_test.cpp
r878 r886 36 36 g1->set_rv ( b ); 37 37 38 Array< const epdf*> coms ( 2 );39 coms ( 0 ) = g0 .get();40 coms ( 1 ) = g1 .get();38 Array<shared_ptr<epdf> > coms ( 2 ); 39 coms ( 0 ) = g0; 40 coms ( 1 ) = g1; 41 41 42 42 eprod p; … … 44 44 // pointers in the array to outlast the eprod instance... 45 45 p.set_parameters ( coms ); 46 p.validate(); 46 47 47 48 CHECK_EQUAL ( vec ( "1 10 10" ), p.mean() );