Changeset 477 for library/bdm/stat/exp_family.cpp
- Timestamp:
- 08/05/09 14:40:03 (15 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/stat/exp_family.cpp
r471 r477 4 4 #include "exp_family.h" 5 5 6 namespace bdm {6 namespace bdm { 7 7 8 8 Uniform_RNG UniRNG; … … 12 12 using std::cout; 13 13 14 void BMEF::bayes ( const vec &dt ) {this->bayes ( dt,1.0 );}; 14 void BMEF::bayes ( const vec &dt ) { 15 this->bayes ( dt, 1.0 ); 16 }; 15 17 16 18 vec egiw::sample() const { … … 20 22 21 23 double egiw::evallog_nn ( const vec &val ) const { 22 int vend = val.length() -1;23 24 if ( dimx ==1 ) { //same as the following, just quicker.24 int vend = val.length() - 1; 25 26 if ( dimx == 1 ) { //same as the following, just quicker. 25 27 double r = val ( vend ); //last entry! 26 if ( r<0) return -inf;27 vec Psi ( nPsi +dimx );28 if ( r < 0 ) return -inf; 29 vec Psi ( nPsi + dimx ); 28 30 Psi ( 0 ) = -1.0; 29 Psi.set_subvector ( 1,val ( 0,vend-1 ) ); // fill the rest 30 31 double Vq=V.qform ( Psi ); 32 return -0.5* ( nu*log ( r ) + Vq /r ); 33 } 34 else { 35 mat Th= reshape ( val ( 0,nPsi*dimx-1 ),nPsi,dimx ); 36 fsqmat R ( reshape ( val ( nPsi*dimx,vend ),dimx,dimx ) ); 37 double ldetR=R.logdet(); 38 if (ldetR) return -inf; 39 mat Tmp=concat_vertical ( -eye ( dimx ),Th ); 31 Psi.set_subvector ( 1, val ( 0, vend - 1 ) ); // fill the rest 32 33 double Vq = V.qform ( Psi ); 34 return -0.5* ( nu*log ( r ) + Vq / r ); 35 } else { 36 mat Th = reshape ( val ( 0, nPsi * dimx - 1 ), nPsi, dimx ); 37 fsqmat R ( reshape ( val ( nPsi*dimx, vend ), dimx, dimx ) ); 38 double ldetR = R.logdet(); 39 if ( ldetR ) return -inf; 40 mat Tmp = concat_vertical ( -eye ( dimx ), Th ); 40 41 fsqmat iR ( dimx ); 41 42 R.inv ( iR ); … … 48 49 const vec& D = V._D(); 49 50 50 double m = nu - nPsi - dimx-1;51 double m = nu - nPsi - dimx - 1; 51 52 #define log2 0.693147180559945286226763983 52 53 #define logpi 1.144729885849400163877476189 … … 54 55 #define Inf std::numeric_limits<double>::infinity() 55 56 56 double nkG = 0.5 * dimx* ( -nPsi *log2pi + sum ( log ( D ( dimx,D.length()-1 ) ) ) );57 double nkG = 0.5 * dimx * ( -nPsi * log2pi + sum ( log ( D ( dimx, D.length() - 1 ) ) ) ); 57 58 // temporary for lgamma in Wishart 58 double lg=0; 59 for ( int i =0; i<dimx;i++ ) {lg+=lgamma ( 0.5* ( m-i ) );} 60 61 double nkW = 0.5* ( m*sum ( log ( D ( 0,dimx-1 ) ) ) ) \ 62 - 0.5*dimx* ( m*log2 + 0.5* ( dimx-1 ) *log2pi ) - lg; 63 64 it_assert_debug ( ( ( -nkG-nkW ) >-Inf ) && ( ( -nkG-nkW ) <Inf ), "ARX improper" ); 65 return -nkG-nkW; 59 double lg = 0; 60 for ( int i = 0; i < dimx; i++ ) { 61 lg += lgamma ( 0.5 * ( m - i ) ); 62 } 63 64 double nkW = 0.5 * ( m * sum ( log ( D ( 0, dimx - 1 ) ) ) ) \ 65 - 0.5 * dimx * ( m * log2 + 0.5 * ( dimx - 1 ) * log2pi ) - lg; 66 67 it_assert_debug ( ( ( -nkG - nkW ) > -Inf ) && ( ( -nkG - nkW ) < Inf ), "ARX improper" ); 68 return -nkG - nkW; 66 69 } 67 70 68 71 vec egiw::est_theta() const { 69 if ( dimx ==1 ) {72 if ( dimx == 1 ) { 70 73 const mat &L = V._L(); 71 74 int end = L.rows() - 1; 72 75 73 mat iLsub = ltuinv ( L ( dimx,end,dimx,end ) ); 74 75 vec L0 = L.get_col(0); 76 77 return iLsub * L0(1,end); 78 } 79 else { 80 it_error("ERROR: est_theta() not implemented for dimx>1"); 76 mat iLsub = ltuinv ( L ( dimx, end, dimx, end ) ); 77 78 vec L0 = L.get_col ( 0 ); 79 80 return iLsub * L0 ( 1, end ); 81 } else { 82 it_error ( "ERROR: est_theta() not implemented for dimx>1" ); 81 83 return 0; 82 84 } … … 89 91 int end = D.length() - 1; 90 92 91 mat Lsub = L ( 1, end, 1, end); 92 mat Dsub = diag(D(1, end)); 93 94 return inv( transpose(Lsub) * Dsub * Lsub ); 95 96 } 97 else { 98 it_error("ERROR: est_theta_cov() not implemented for dimx>1"); 93 mat Lsub = L ( 1, end, 1, end ); 94 mat Dsub = diag ( D ( 1, end ) ); 95 96 return inv ( transpose ( Lsub ) * Dsub * Lsub ); 97 98 } else { 99 it_error ( "ERROR: est_theta_cov() not implemented for dimx>1" ); 99 100 return 0; 100 101 } … … 104 105 vec egiw::mean() const { 105 106 106 if ( dimx ==1 ) {107 const vec &D = V._D();108 int end = D.length() -1;107 if ( dimx == 1 ) { 108 const vec &D = V._D(); 109 int end = D.length() - 1; 109 110 110 111 vec m ( dim ); 111 112 m.set_subvector ( 0, est_theta() ); 112 m ( end ) = D ( 0 ) / ( nu - nPsi -2*dimx -2 );113 m ( end ) = D ( 0 ) / ( nu - nPsi - 2 * dimx - 2 ); 113 114 return m; 114 } 115 else { 115 } else { 116 116 mat M; 117 117 mat R; 118 mean_mat ( M, R );119 return cvectorize ( concat_vertical ( M, R ) );118 mean_mat ( M, R ); 119 return cvectorize ( concat_vertical ( M, R ) ); 120 120 } 121 121 … … 124 124 vec egiw::variance() const { 125 125 126 if ( dimx ==1 ) {127 int l =V.rows();128 const ldmat tmp (V,linspace(1,l-1));129 ldmat itmp (l);130 tmp.inv (itmp);131 double cove = V._D() ( 0 ) / ( nu - nPsi -2*dimx -2 );132 133 vec var (l);134 var.set_subvector (0,diag(itmp.to_mat())*cove);135 var (l-1)=cove*cove/( nu -nPsi -2*dimx -2 );126 if ( dimx == 1 ) { 127 int l = V.rows(); 128 const ldmat tmp ( V, linspace ( 1, l - 1 ) ); 129 ldmat itmp ( l ); 130 tmp.inv ( itmp ); 131 double cove = V._D() ( 0 ) / ( nu - nPsi - 2 * dimx - 2 ); 132 133 vec var ( l ); 134 var.set_subvector ( 0, diag ( itmp.to_mat() ) *cove ); 135 var ( l - 1 ) = cove * cove / ( nu - nPsi - 2 * dimx - 2 ); 136 136 return var; 137 } 138 else {it_error("not implemented"); return vec(0);} 137 } else { 138 it_error ( "not implemented" ); 139 return vec ( 0 ); 140 } 139 141 } 140 142 141 143 void egiw::mean_mat ( mat &M, mat&R ) const { 142 const mat &L = V._L();143 const vec &D = V._D();144 int end = L.rows() -1;145 146 ldmat ldR ( L ( 0, dimx-1,0,dimx-1 ), D ( 0,dimx-1 ) / ( nu -nPsi -2*dimx -2 ) ); //exp val of R147 mat iLsub =ltuinv ( L ( dimx,end,dimx,end ) );144 const mat &L = V._L(); 145 const vec &D = V._D(); 146 int end = L.rows() - 1; 147 148 ldmat ldR ( L ( 0, dimx - 1, 0, dimx - 1 ), D ( 0, dimx - 1 ) / ( nu - nPsi - 2*dimx - 2 ) ); //exp val of R 149 mat iLsub = ltuinv ( L ( dimx, end, dimx, end ) ); 148 150 149 151 // set mean value 150 mat Lpsi = L ( dimx, end,0,dimx-1 );151 M = iLsub*Lpsi;152 R = ldR.to_mat() ;152 mat Lpsi = L ( dimx, end, 0, dimx - 1 ); 153 M = iLsub * Lpsi; 154 R = ldR.to_mat() ; 153 155 } 154 156 155 157 vec egamma::sample() const { 156 vec smp ( dim );158 vec smp ( dim ); 157 159 int i; 158 160 159 for ( i=0; i<dim; i++ ) { 160 if ( beta ( i ) >std::numeric_limits<double>::epsilon() ) { 161 GamRNG.setup ( alpha ( i ),beta ( i ) ); 162 } 163 else { 164 GamRNG.setup ( alpha ( i ),std::numeric_limits<double>::epsilon() ); 161 for ( i = 0; i < dim; i++ ) { 162 if ( beta ( i ) > std::numeric_limits<double>::epsilon() ) { 163 GamRNG.setup ( alpha ( i ), beta ( i ) ); 164 } else { 165 GamRNG.setup ( alpha ( i ), std::numeric_limits<double>::epsilon() ); 165 166 } 166 167 #pragma omp critical … … 190 191 int i; 191 192 192 if ( any(val<=0.)) return -inf;193 if ( any(beta<=0.)) return -inf;194 for ( i =0; i<dim; i++ ) {195 res += ( alpha ( i ) - 1 ) * std::log ( val ( i ) ) - beta ( i ) *val ( i );196 } 197 double tmp =res-lognc();;198 it_assert_debug ( std::isfinite ( tmp ), "Infinite value" );193 if ( any ( val <= 0. ) ) return -inf; 194 if ( any ( beta <= 0. ) ) return -inf; 195 for ( i = 0; i < dim; i++ ) { 196 res += ( alpha ( i ) - 1 ) * std::log ( val ( i ) ) - beta ( i ) * val ( i ); 197 } 198 double tmp = res - lognc();; 199 it_assert_debug ( std::isfinite ( tmp ), "Infinite value" ); 199 200 return tmp; 200 201 } … … 204 205 int i; 205 206 206 for ( i =0; i<dim; i++ ) {207 res += lgamma ( alpha ( i ) ) - alpha ( i ) * std::log ( beta ( i ) ) ;207 for ( i = 0; i < dim; i++ ) { 208 res += lgamma ( alpha ( i ) ) - alpha ( i ) * std::log ( beta ( i ) ) ; 208 209 } 209 210 … … 211 212 } 212 213 213 void mgamma::set_parameters (double k0, const vec &beta0) {214 void mgamma::set_parameters ( double k0, const vec &beta0 ) { 214 215 k = k0; 215 iepdf->set_parameters (k * ones(beta0.length()), beta0);216 iepdf->set_parameters ( k * ones ( beta0.length() ), beta0 ); 216 217 dimc = e()->dimension(); 217 218 } 218 219 219 ivec eEmp::resample ( RESAMPLING_METHOD method) {220 ivec ind =zeros_i ( n );220 ivec eEmp::resample ( RESAMPLING_METHOD method ) { 221 ivec ind = zeros_i ( n ); 221 222 ivec N_babies = zeros_i ( n ); 222 223 vec cumDist = cumsum ( w ); 223 224 vec u ( n ); 224 int i, j,parent;225 int i, j, parent; 225 226 double u0; 226 227 227 228 switch ( method ) { 228 229 230 231 for ( i = n - 2;i >= 0;i-- ) {232 233 234 235 236 237 238 239 for ( i = 0;i < n;i++ ) {240 241 242 243 244 245 246 247 248 for ( i = 0;i < n;i++ ) {249 250 251 252 253 254 255 229 case MULTINOMIAL: 230 u ( n - 1 ) = pow ( UniRNG.sample(), 1.0 / n ); 231 232 for ( i = n - 2; i >= 0; i-- ) { 233 u ( i ) = u ( i + 1 ) * pow ( UniRNG.sample(), 1.0 / ( i + 1 ) ); 234 } 235 236 break; 237 238 case STRATIFIED: 239 240 for ( i = 0; i < n; i++ ) { 241 u ( i ) = ( i + UniRNG.sample() ) / n; 242 } 243 244 break; 245 246 case SYSTEMATIC: 247 u0 = UniRNG.sample(); 248 249 for ( i = 0; i < n; i++ ) { 250 u ( i ) = ( i + u0 ) / n; 251 } 252 253 break; 254 255 default: 256 it_error ( "PF::resample(): Unknown resampling method" ); 256 257 } 257 258 … … 259 260 j = 0; 260 261 261 for ( i = 0; i < n;i++ ) {262 for ( i = 0; i < n; i++ ) { 262 263 while ( u ( i ) > cumDist ( j ) ) j++; 263 264 … … 270 271 271 272 // find the first parent; 272 parent=0; while ( N_babies ( parent ) ==0 ) parent++; 273 parent = 0; 274 while ( N_babies ( parent ) == 0 ) parent++; 273 275 274 276 // Build index 275 for ( i = 0; i < n;i++ ) {277 for ( i = 0; i < n; i++ ) { 276 278 if ( N_babies ( i ) > 0 ) { 277 279 ind ( i ) = i; 278 280 N_babies ( i ) --; //this index was now replicated; 279 } 280 else { 281 } else { 281 282 // test if the parent has been fully replicated 282 283 // if yes, find the next one 283 while ( ( N_babies ( parent ) == 0 ) || ( N_babies ( parent ) ==1 && parent>i ) ) parent++;284 while ( ( N_babies ( parent ) == 0 ) || ( N_babies ( parent ) == 1 && parent > i ) ) parent++; 284 285 285 286 // Replicate parent … … 292 293 293 294 // copy the internals according to ind 294 for ( i =0;i<n;i++ ) {295 if ( ind ( i ) != i ) {296 samples ( i ) = samples ( ind ( i ) );297 } 298 w ( i ) = 1.0 /n;295 for ( i = 0; i < n; i++ ) { 296 if ( ind ( i ) != i ) { 297 samples ( i ) = samples ( ind ( i ) ); 298 } 299 w ( i ) = 1.0 / n; 299 300 } 300 301 … … 305 306 //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); 306 307 dim = epdf0->dimension(); 307 w =w0;308 w /=sum ( w0 );//renormalize309 n =w.length();308 w = w0; 309 w /= sum ( w0 );//renormalize 310 n = w.length(); 310 311 samples.set_size ( n ); 311 312 dim = epdf0->dimension(); 312 313 313 for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();} 314 for ( int i = 0; i < n; i++ ) { 315 samples ( i ) = epdf0->sample(); 316 } 314 317 } 315 318 316 319 void eEmp::set_samples ( const epdf* epdf0 ) { 317 320 //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); 318 w=1; 319 w/=sum ( w );//renormalize 320 321 for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();} 322 } 323 324 void migamma_ref::from_setting( const Setting &set ) 325 { 321 w = 1; 322 w /= sum ( w );//renormalize 323 324 for ( int i = 0; i < n; i++ ) { 325 samples ( i ) = epdf0->sample(); 326 } 327 } 328 329 void migamma_ref::from_setting ( const Setting &set ) { 326 330 vec ref; 327 UI::get( ref, set, "ref" , UI::compulsory); 328 set_parameters(set["k"],ref,set["l"]); 329 } 330 331 void mlognorm::from_setting( const Setting &set ) 332 { 333 vec mu0; 334 UI::get( mu0, set, "mu0", UI::compulsory); 335 set_parameters(mu0.length(),set["k"]); 336 condition(mu0); 331 UI::get ( ref, set, "ref" , UI::compulsory ); 332 set_parameters ( set["k"], ref, set["l"] ); 333 } 334 335 void mlognorm::from_setting ( const Setting &set ) { 336 vec mu0; 337 UI::get ( mu0, set, "mu0", UI::compulsory ); 338 set_parameters ( mu0.length(), set["k"] ); 339 condition ( mu0 ); 337 340 } 338 341