MCMC.cpp

Go to the documentation of this file.
00001 /// \file   MCMC.cpp
00002 /// \brief  Definitions of classes for MCMC evaluation of Bayesian models
00003 ///
00004 /// The Parameter, Step, and Model classes defined here are the core classes
00005 /// that do all of the work. To implement a Bayesian model using these classes
00006 /// each parameter in the model should be derived from Paramater and should
00007 /// override llike(), at a minimum. lprior() should be overridden for
00008 /// anything other than a flat prior. (Notice that the prior will be
00009 /// improper unless overriden when the parameter has an unbounded domain.)
00010 /// The model is derived from Model, and each parameter is pushed onto a
00011 /// stack (step_), with a specified Step type (MetroStep, SliceStep, or
00012 /// FunctionStep).
00013 ///
00014 /// \author Kent Holsinger
00015 /// \date   2005-05-18
00016 ///
00017 
00018 // This file is part of MCMC++, a library for constructing C++ programs
00019 // that implement MCMC analyses of Bayesian statistical models.
00020 // Copyright (c) 2004-2006 Kent E. Holsinger
00021 //
00022 // MCMC++ is free software; you can redistribute it and/or modify
00023 // it under the terms of the GNU General Public License as published by
00024 // the Free Software Foundation; either version 2 of the License, or
00025 // (at your option) any later version.
00026 //
00027 // MCMC++ is distributed in the hope that it will be useful,
00028 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00029 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00030 // GNU General Public License for more details.
00031 //
00032 // You should have received a copy of the GNU General Public License
00033 // along with MCMC++; if not, write to the Free Software
00034 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00035 //
00036 
00037 // standard includes
00038 #include <iostream>
00039 // local includes
00040 #include "mcmc++/Density.h"
00041 #include "mcmc++/MCMC.h"
00042 #include "mcmc++/intervals.h"
00043 
00044 using std::copy;
00045 using std::endl;
00046 using std::ostream;
00047 using std::vector;
00048 using boost::any;
00049 using boost::any_cast;
00050 using Density::dbeta;
00051 using Density::dnorm;
00052 
00053 /// argCheck_ controls whether arguments are bounds checked
00054 /// before use
00055 ///
00056 /// Defaults to 1 (true) unles NDEBUG is defined
00057 ///
00058 #if defined(NDEBUG)
00059 #define argCheck_ 0
00060 #else
00061 #define argCheck_ 1
00062 #endif
00063 
00064 struct BadValue {};
00065 struct BadCT {};
00066 
00067 /// Macro to determine whether a value isnan() and print __FILE__ and 
00068 /// __LINE__ if it is (disabled when argCheck == 0 (i.e., when NDEBUG
00069 /// is defined during compilation
00070 ///
00071 #if defined(HAVE_ISNAN) && !defined(MINGW32) && !defined(__CYGWIN__)
00072 extern "C" { int isnan(double x); }
00073 #define checkValue_(x) \
00074   if (argCheck_ && isnan(x)) {       \
00075     std::cout << __FILE__ << ": " << __LINE__ << std::endl;  \
00076   } \
00077   Util::Assert<BadValue>(!argCheck_ || !isnan(x))
00078 #else
00079 #define checkValue_(x) ;
00080 #endif
00081 
00082 // MCMC uses the Mersenne twister on (0,1) by default, because the slice 
00083 // sampler requires it. Notice that the non-uniform RNGs in lot are 
00084 // validated with the Mersenne twister on [0,1). It's conceivable that
00085 // this might affect the accuracy of Metropolis-Hastings steps, but I 
00086 // don't <b>think</b> it will make much difference. The underlying sequence 
00087 // of integers is the same. Each value from the (0,1) version of the MT 
00088 // exceeds the corresponding value from the [0,1) version by 
00089 // \f$0.5/4294967296.0 < 1.2 \times 10^{-10}\f$. If you're paranoid,
00090 // you can override the proposal functions in Parameter and Set_MT(ZERO).
00091 //
00092 namespace {
00093 
00094   lot rng_(lot::RAN_MT, lot::OPEN);   ///< RNG used in all classes (static)
00095 
00096 }
00097 
00098 /// default "zero" value for safeFreq()
00099 ///
00100 const double MCMC_ZERO_FREQ = 1.00e-14;
00101 
00102 /// Returns a reference to the internal random number generator
00103 ///
00104 lot& GetRNG(void) {
00105   return rng_;
00106 }
00107 
00108 /// Ensures zero < p < 1-zero
00109 ///
00110 /// \param p    Frequency to guard
00111 /// \param zero Minimum value of p allowed
00112 ///
00113 /// Assumes all elements of p are in [0, 1]
00114 ///
00115 double safeFreq(const double p, const double zero) {
00116   return p*(1.0 - 2.0*zero) + zero;
00117 }
00118 
00119 /// Converts a safeFreq()ed x back
00120 ///
00121 /// \param x    Frequency to convert back
00122 /// \param zero Value used in original guard (not verified)
00123 ///
00124 double invSafeFreq(const double x, const double zero) {
00125   double p = (x - zero) / (1.0 - 2.0 * zero);
00126   return p;
00127 }
00128 
00129 /// Ensures that all values in vector are greater than zero and
00130 /// less than 1.0 - n*zero, where n is p.size()
00131 ///
00132 /// \param p    Frequency vector to guard
00133 /// \param zero Value used for guard (MCMC_ZERO_FREQ default)
00134 ///
00135 /// Assumes all elements of p are in [0, 1]
00136 ///
00137 std::vector<double>
00138 safeFreq(const std::vector<double>& p, const double zero) {
00139   std::vector<double> q(p.size());
00140   int nElem = q.size();
00141   for (unsigned i = 0; i < nElem; i++) {
00142     q[i] = p[i] * (1.0 - nElem*zero) + zero;
00143   }
00144   return q;
00145 }
00146 
00147 /// Inverts a safeFreq()ed vector
00148 ///
00149 /// \param x        The vector to invert
00150 /// \param zero     The original guard (not checked)
00151 ///
00152 std::vector<double>
00153 invSafeFreq(const std::vector<double>& x,
00154             const double zero) 
00155 {
00156   unsigned nElem = x.size();
00157   std::vector<double> q(nElem);
00158   for (unsigned k = 0; k < nElem; ++k) {
00159     q[k] = (x[k] - zero)/(1.0 - nElem*zero);
00160   }
00161   return q;
00162 }
00163 
00164 
00165 /// Propose a new beta variate for an M-H step
00166 ///
00167 /// \param mean      Mean for beta distribution
00168 /// \param denom     Effective sample size
00169 /// \param tolerance Minimum value allowed (to avoid exact 0s and 1s)
00170 ///
00171 /// The parameters of the beta distribution are given by
00172 ///
00173 /// \f[\alpha = denom \times mean\f]
00174 /// \f[\beta  = denom \times (1-mean)\f]
00175 ///
00176 /// where alpha and beta are guarded by safeBetaPar()
00177 ///
00178 double proposeBeta(const double mean, const double denom, 
00179                        const double tolerance) 
00180 {
00181   double alphaProposal, betaProposal;
00182   alphaProposal = safeBetaPar(denom * mean);
00183   betaProposal = safeBetaPar(denom - alphaProposal);
00184   // select a new value for p
00185   double p = rng_.beta(alphaProposal, betaProposal);
00186   return safeFreq(p, tolerance);
00187 }
00188 
00189 /// lQ for a beta proposal
00190 ///
00191 /// \param newMean   New value proposed
00192 /// \param oldMean   Old value from which proposed
00193 /// \param denom     Effective sample size
00194 /// \param tolerance Minimum value allowed in original proposal
00195 ///
00196 double logQBeta(const double newMean, const double oldMean,
00197                     const double denom, const double tolerance)
00198 {
00199   double alphaProposal = safeBetaPar(denom * oldMean);
00200   double betaProposal = safeBetaPar(denom - alphaProposal);
00201   double p = invSafeFreq(newMean, tolerance);
00202   double value = dbeta(p, alphaProposal, betaProposal, true);
00203   return Util::safeLog(value);
00204 }
00205 
00206 /// Propose a new Dirichlet vector for an M-H step
00207 ///
00208 /// \param q         Mean of the proposal distribution
00209 /// \param denom     Effective sample size
00210 /// \param tolerance Minimum value allowed (to avoid exact 0s and 1s)
00211 ///
00212 /// The parameters of the beta distribution are given by
00213 ///
00214 /// \f[\alpha = denom \times mean\f]
00215 /// \f[\beta  = denom \times (1-mean)\f]
00216 ///
00217 /// where alpha and beta are guarded by safeBetaPar()
00218 ///
00219 std::vector<double>
00220 proposeDirch(const std::vector<double>& q, const double denom,
00221              const double tolerance) 
00222 {
00223   unsigned nElem = q.size();
00224   std::vector<double> alpha(nElem);
00225   for (unsigned i = 0; i < nElem; i++) {
00226     alpha[i] = q[i]*denom;
00227   }
00228   safeDirchPar(alpha);
00229   std::vector<double> p = rng_.dirichlet(alpha);
00230   std::vector<double> r = safeFreq(p, tolerance);
00231   return r;
00232 }
00233 
00234 /// lQ for a Dirichlet proposal
00235 ///
00236 /// \param newMean   New value proposed
00237 /// \param oldMean   Old value from which proposed
00238 /// \param denom     Effective sample size
00239 /// \param tolerance Minimum value allowed in original proposal
00240 ///
00241 double
00242 logQDirch(const std::vector<double>& newMean,
00243           const std::vector<double>& oldMean,
00244           const double denom, const double tolerance)
00245 {
00246   int nElem = newMean.size();
00247   std::vector<double> alpha(nElem);
00248   for (unsigned k = 0; k < nElem; ++k) {
00249     alpha[k] = denom * oldMean[k];
00250   }
00251   std::vector<double> p = invSafeFreq(newMean, tolerance);
00252   double value = Density::ddirch(p, alpha, true);
00253   return Util::safeLog(value);
00254 }
00255 
00256 /// Propose a new normal variate for an M-H step
00257 ///
00258 /// \param mean     Mean of the proposal distribution
00259 /// \param variance Variance of the proposal distribution
00260 ///
00261 double proposeNorm(const double mean, const double variance) {
00262   return rng_.norm(mean, variance);
00263 }
00264 
00265 /// lQ for a normal proposal
00266 ///
00267 /// \param newMean   New value proposed
00268 /// \param oldMean   Old value from which proposed
00269 /// \param variance  Variance of the proposal distribution
00270 ///
00271 double logQNorm(const double newMean, const double oldMean,
00272                     const double variance)
00273 {
00274   double value = dnorm(newMean, oldMean, variance, true);
00275   return Util::safeLog(value);
00276 }
00277 
00278 /// Ensures MinBetaPar <= x <= MaxBetaPar
00279 ///
00280 /// \param x    Frequency to guard
00281 ///
00282 double safeBetaPar(const double x) {
00283   using MCMC::MinBetaPar;
00284   using MCMC::MaxBetaPar;
00285   return (x < MinBetaPar) ? MinBetaPar : (x > MaxBetaPar) ? MaxBetaPar : x;
00286 }
00287 
00288 /// Ensures MinBetaPar <= x <= MaxBetaPar for all elements of a 
00289 /// Dirichlet parameter vector
00290 ///
00291 /// \param x    Frequency to guard
00292 ///
00293 void safeDirchPar(std::vector<double>& x) {
00294   using MCMC::MinDirchPar;
00295   using MCMC::MaxDirchPar;
00296   int nElem = x.size();
00297   for (int i = 0; i < nElem; ++i) {
00298     x[i] = (x[i] < MinDirchPar) ? MinDirchPar : 
00299       (x[i] > MaxDirchPar) ? MaxDirchPar : x[i];
00300   }
00301 }
00302 
00303 /// Constructor
00304 ///
00305 /// \param label    a string identifier for the parameter
00306 ///
00307 /// Used internally to construct Parameter classes. Not intended for direct
00308 /// use.
00309 ParameterBase::ParameterBase(std::string label)
00310   : label_(label)
00311 {}
00312 
00313 /// Destructor
00314 ///
00315 ParameterBase::~ParameterBase(void) 
00316 {}
00317 
00318 /// Adapt the proposal distribution in a Metropolis-Hastings sampler
00319 ///
00320 /// \param accept  the current acceptance percentage
00321 ///
00322 void 
00323 ParameterBase::Adapt(const double accept) {}
00324 
00325 /// internal typedef, defined here so that it is invisible and
00326 /// inaccessible to users of the library
00327 ///
00328 typedef ParameterT<double> dPar;
00329 /// internal typedef, defined here so that it is invisible and
00330 /// inaccessible to users of the library
00331 ///
00332 typedef ParameterT<int> iPar;
00333 /// internal typedef, defined here so that it is invisible and
00334 /// inaccessible to users of the library
00335 ///
00336 typedef ParameterT<std::vector<double> > dVecPar;
00337 /// internal typedef, defined here so that it is invisible and
00338 /// inaccessible to users of the library
00339 ///
00340 typedef ParameterT<std::vector<int> > iVecPar;
00341 /// internal typedef, defined here so that it is invisible and
00342 /// inaccessible to users of the library
00343 ///
00344 typedef ParameterT<boost::any> aPar;
00345 
00346 /// sets value of the parameter
00347 ///
00348 /// \param value the value to be assigned
00349 ///
00350 void
00351 ParameterBase::Assign(const boost::any& value) {
00352   struct UnsupportedParameterType {} ;
00353 
00354   if (dPar* q = dynamic_cast<dPar*>(this)) {
00355     return q->Assign(any_cast<double>(value));
00356   } else if (iPar* q = dynamic_cast<iPar*>(this)) {
00357     return q->Assign(any_cast<int>(value));
00358   } else if (dVecPar* q = dynamic_cast<dVecPar* >(this)) {
00359     return q->Assign(any_cast<vector<double> >(value));
00360   } else if (iVecPar* q = dynamic_cast<iVecPar* >(this)) {
00361     return q->Assign(any_cast<vector<int> >(value));
00362   } else if (aPar* q = dynamic_cast<aPar*>(this) ) {
00363     return q->Assign(value);
00364   } else {
00365     throw UnsupportedParameterType();
00366   }
00367 }
00368 
00369 
00370 /// Returns string identifying current parameter
00371 ///
00372 /// The default value is an empty string. Replace it by including an
00373 /// argument to the constructor 
00374 ///
00375 std::string 
00376 ParameterBase::Label(void) const {
00377   return label_;
00378 }
00379 
00380 /// Set the label associated with this parameter
00381 ///
00382 /// \param label  the label string
00383 ///
00384 void 
00385 ParameterBase::SetLabel(const std::string& label) {
00386   label_ = label;
00387 }
00388 
00389 /// internal typedef, defined here so that it is invisible and
00390 /// inaccessible to users of the library
00391 ///
00392 typedef const ParameterT<double> cdPar;
00393 /// internal typedef, defined here so that it is invisible and
00394 /// inaccessible to users of the library
00395 ///
00396 typedef const ParameterT<int> ciPar;
00397 /// internal typedef, defined here so that it is invisible and
00398 /// inaccessible to users of the library
00399 ///
00400 typedef const ParameterT<std::vector<double> > cdVecPar;
00401 /// internal typedef, defined here so that it is invisible and
00402 /// inaccessible to users of the library
00403 ///
00404 typedef const ParameterT<std::vector<int> > ciVecPar;
00405 /// internal typedef, defined here so that it is invisible and
00406 /// inaccessible to users of the library
00407 ///
00408 typedef const ParameterT<boost::any> caPar;
00409 
00410 /// Value of the parameter
00411 ///
00412 const boost::any 
00413 ParameterBase::Value(void) const {
00414   struct UnsupportedParameterType {} ;
00415 
00416   if (cdPar* q = dynamic_cast<cdPar*>(this)) {
00417     return q->Value();
00418   } else if (ciPar* q = dynamic_cast<ciPar*>(this)) {
00419     return q->Value();
00420   } else if (cdVecPar* q = dynamic_cast<cdVecPar* >(this)) {
00421     return q->Value();
00422   } else if (ciVecPar* q = dynamic_cast<ciVecPar* >(this)) {
00423     return q->Value();
00424   } else if (caPar* q = dynamic_cast<caPar*>(this) ) {
00425     return q->Value();
00426   } else {
00427     throw UnsupportedParameterType();
00428   }
00429 }
00430 
00431 /// Constructor
00432 ///
00433 /// Used internally to construct Step classes. Not intended for direct
00434 /// use.
00435 ///
00436 StepBase::StepBase(ParameterBase* parameter, unsigned long accept, 
00437                    unsigned long ct, const double w, const double m, 
00438                    const double lowBound, const double highBound) 
00439   : par_(parameter), accept_(accept), ct_(ct), w_(w), m_(m),
00440     lowBound_(lowBound), highBound_(highBound)
00441 {}
00442 
00443 /// Destructor
00444 ///
00445 StepBase::~StepBase(void) 
00446 {}
00447 
00448 /// Number of proposals accepted (for M-H)
00449 ///
00450 int 
00451 StepBase::accept(void) const {
00452   return accept_;
00453 }
00454 
00455 /// Label of parameter associated with this step
00456 ///
00457 std::string 
00458 StepBase::Label(void) const {
00459   return par_->Label();
00460 }
00461 
00462 /// Parameter associated with this step
00463 ///
00464 ParameterBase*
00465 StepBase::Par(void) const {
00466   return par_;
00467 }
00468 
00469 /// Reset acceptance statistics (for M-H)
00470 ///
00471 void 
00472 StepBase::ResetAccept(void) {
00473   accept_ = 0;
00474 }
00475 
00476 /// Set the label associated with this step
00477 ///
00478 /// \param label  the label string
00479 ///
00480 void 
00481 StepBase::SetLabel(const std::string& label) {
00482   par_->SetLabel(label);
00483 }
00484 
00485 /// Returns parameter value of the current step
00486 ///
00487 /// Assumes value stored as boost::any
00488 ///
00489 const boost::any 
00490 StepBase::aValue(void) const {
00491   return par_->Value();
00492 }
00493 
00494 /// Returns parameter value of the current step
00495 ///
00496 /// Assumes value stored as double
00497 ///
00498 const double
00499 StepBase::Value(void) const {
00500   dPar* q = dynamic_cast<dPar*>(par_);
00501   return q->Value();
00502 }
00503 
00504 /// Returns parameter value of the current step
00505 ///
00506 /// Assumes value stored as integer
00507 ///
00508 const int 
00509 StepBase::iValue(void) const {
00510   iPar* q = dynamic_cast<iPar*>(par_);
00511   return q->Value();
00512 }
00513 
00514 /// Returns parameter value of the current step
00515 ///
00516 /// Assumes value stored as vector<double>
00517 ///
00518 const vector<double>
00519 StepBase::dVecValue(void) const {
00520   dVecPar* q = dynamic_cast<dVecPar*>(par_);
00521   return q->Value();
00522 }
00523 
00524 /// Returns parameter value of the current step
00525 ///
00526 /// Assumes value stored as vector<int>
00527 ///
00528 const vector<int>
00529 StepBase::iVecValue(void) const {
00530   iVecPar* q = dynamic_cast<iVecPar*>(par_);
00531   return q->Value();
00532 }
00533 
00534 
00535 const double SliceStep::DefaultW = 1.0;   ///< default "step out" width
00536 const long SliceStep::MUnbounded = -1;    ///< unlimited number of steps out allowed by default
00537 
00538 /// Constructor
00539 ///
00540 /// \param parameter  Pointer to the parameter associated with this step
00541 ///
00542 /// The "step out" width is set to 1, unless the parameter has defined
00543 /// W() and returns a value > 0.0. The "step out" procedure is set to do
00544 /// an unlimited number of steps, unless the parameter has defined M()
00545 /// and returns a value > 0.
00546 ///
00547 /// Notice that the defaults will result in the slice sampler adapting
00548 /// the "step out" width as the simulation proceeds. Adapting the width is
00549 /// permissible <b>only</b> when the distribution is unimodal. If you're not
00550 /// sure that your distribution is unimodal, you should define W() and M() to
00551 /// return values that seem reasonable to you.
00552 ///
00553 SliceStep::SliceStep(Parameter* parameter) 
00554   : Step<double>(parameter, SliceStep::DefaultW, SliceStep::MUnbounded, 
00555                  -Util::dbl_max, Util::dbl_max), dbl_(parameter),
00556     llike_(&Parameter::llike), lPrior_(&Parameter::lPrior)
00557 {
00558   ct_ = 0;   // I don't think this should be necessary, since ct_(0) is
00559              // included in the initialization for Step(), but it fails
00560              // on some calls if it's not included
00561 }
00562 
00563 /// Sets upper and lower limits on values allowed
00564 ///
00565 /// \param low  Lower bound on parameter
00566 /// \param high Upper bound on parameter
00567 ///
00568 /// For parameters that are bounded, e.g., frequencies on [0,1], setting
00569 /// bounds on allowable values helps avoid numerical problems in evaluating
00570 /// likelihoods and priors.
00571 ///
00572 void 
00573 SliceStep::SetBounds(const double low, const double high) {
00574   lowBound_ = low;
00575   highBound_ = high;
00576   if ((lowBound_ > -Util::dbl_max) && (highBound_ < Util::dbl_max)) {
00577     w_ = (highBound_ - lowBound_)/10;
00578   }
00579 }
00580 
00581 /// Reset step width
00582 ///
00583 /// \param w  New step width
00584 ///
00585 void 
00586 SliceStep::SetW(const double w) {
00587   w_ = w;
00588 }
00589 
00590 /// Reset number of steps out allowed
00591 ///
00592 /// \param m  New number of steps out allowed
00593 ///
00594 void 
00595 SliceStep::SetM(const int m) {
00596   m_ = m;
00597 }
00598 
00599 /// Assign value to parameter associated with this step
00600 ///
00601 /// \param x  The value to assign
00602 ///
00603 void 
00604 SliceStep::Assign(const double x) {
00605   dbl_->Assign(x);
00606 }
00607 
00608 /// Return a new value from the slice sampler
00609 ///
00610 void
00611 SliceStep::DoStep(void) {
00612   double x = dbl_->Value();
00613   SetSlice(x);
00614   dbl_->Assign(Sample(x));
00615 }
00616 
00617 /// "stepping out" version of slice sampler
00618 ///
00619 /// \param x   current value of parameter
00620 ///
00621 /// N.B.: uniform on (0,1), not [0,1) or [0,1], required throughout 
00622 /// SetSlice() and Sample()
00623 ///
00624 void
00625 SliceStep::SetSlice(const double x0) {
00626   double u = rng_.uniform();
00627   checkValue_(u);
00628   checkValue_(l_);
00629   checkValue_(r_);
00630   checkValue_(x0);
00631   checkValue_(w_);
00632   l_ = std::max(x0 - w_*u, lowBound_);
00633   r_ = std::min(l_ + w_, highBound_);
00634   double v = rng_.uniform();
00635   checkValue_(v);
00636   if (m_ == SliceStep::MUnbounded) {
00637     z_ = (dbl_->*llike_)(x0) + (dbl_->*lPrior_)(x0) - rng_.exponential(1.0);
00638     checkValue_(z_);
00639 
00640     while ((l_ > lowBound_) && (z_ < (dbl_->*llike_)(l_) 
00641                                 + (dbl_->*lPrior_)(l_))) 
00642       {
00643         l_ = std::max(l_ - w_, lowBound_);
00644         checkValue_(l_);
00645       }
00646     
00647     while ((r_ < highBound_) && (z_ < (dbl_->*llike_)(r_) 
00648                                  + (dbl_->*lPrior_)(r_))) 
00649       {
00650         r_ = std::min(r_ + w_, highBound_);
00651         checkValue_(r_);
00652       }
00653 
00654     // adjust width
00655     ++ct_;
00656     w_ = (w_*ct_ + (r_ - l_))/(ct_ + 1);
00657     checkValue_(ct_);
00658  
00659     checkValue_(w_);
00660   } else {
00661     int j = static_cast<int>(floor(m_*v));
00662     int k = static_cast<int>(m_ -  1) - j;
00663     z_ = (dbl_->*llike_)(x0) + (dbl_->*lPrior_)(x0) - rng_.exponential(1.0);
00664     checkValue_(z_);
00665     while ((l_ > lowBound_) 
00666            && (j > 0) && (z_ < (dbl_->*llike_)(l_) + (dbl_->*lPrior_)(l_)))
00667       {
00668         l_ = std::max(l_ - w_, lowBound_);
00669         checkValue_(l_);
00670         --j;
00671       }
00672   
00673     while ((r_ < highBound_)
00674            && (k > 0) && (z_ < (dbl_->*llike_)(r_) + (dbl_->*lPrior_)(r_))) 
00675       {
00676         r_ = std::min(r_ + w_, highBound_);
00677         checkValue_(r_);
00678         --k;
00679       }
00680   }
00681 }
00682 
00683 double
00684 SliceStep::Sample(const double x0) {
00685   double u = rng_.uniform();
00686   double x1 = l_ + u*(r_ - l_);
00687   while (z_ > (dbl_->*llike_)(x1) + (dbl_->*lPrior_)(x1)) {
00688     if (x1 < x0) {
00689       l_ = x1;
00690     } else {
00691       r_ = x1;
00692     }
00693     u = rng_.uniform();
00694     x1 = l_ + u*(r_ - l_);
00695   }
00696   return x1;
00697 }
00698 
00699 /// Value of parameter associated with this step
00700 ///
00701 const double
00702 SliceStep::Value(void) const {
00703   return dbl_->Value();
00704 }
00705 
00706 namespace {
00707   boost::format formatter_("%|12| %|12| %|12| %|12| %|12| %|12|");
00708   boost::format dic_("%|12| %|12|");
00709 }
00710 
00711 // N.B.: nBurnin + nSample <= Util::ulong_max required (but probably
00712 // ensured by use of vector<vector<double> > to hold parameter
00713 // results)
00714 
00715 /// Constructor
00716 ///
00717 /// \param nBurnin  Number of iterations for "burn in"
00718 /// \param nSample  Number of iterations for "sample"
00719 /// \param nThin    Keep every nThin'th sample
00720 /// \param calc     false == no lLike not overridden,
00721 ///                 true == lLike overriden (there's probably a way to
00722 ///                 figure this out, but I haven't worked on it yet).
00723 ///                 Default is false
00724 /// \param useMedian  false == use posterior mean in DIC calculation,
00725 ///                   true == use posterior median in DIC calculation.
00726 ///                   Default is false.
00727 ///
00728 Model::Model(const int nBurnin, const int nSample, const int nThin,
00729              const bool calc, const bool useMedian)
00730   : nBurnin_(nBurnin), nSample_(nSample), nThin_(nThin), nElem_(0),
00731     summaryFormat_(&formatter_), pd_(0), calculateLikelihood_(calc),
00732     useMedian_(useMedian)
00733 {}
00734 
00735 /// Destructor
00736 ///
00737 Model::~Model(void) {}
00738 
00739 /// Invoke simulation to do the analysis
00740 ///
00741 /// \param outf  Output stream for progress display
00742 /// \param interimReport  Produce progress display?
00743 ///
00744 void 
00745 Model::Simulation(std::ostream& outf, const bool interimReport) {
00746   nElem_ = step_.size();
00747   for (int i = 0; i < nBurnin_; ++i) {
00748     Generation();
00749     if (interimReport) {
00750       InterimReport(outf, "Burnin...", i, nBurnin_);
00751     }
00752   }
00753   Reset();
00754   for (int i = 0; i < nSample_; ++i) {
00755     Generation();
00756     if (interimReport) {
00757       InterimReport(outf, "Sample...", i, nSample_);
00758     }
00759     if (((i+1) % nThin_) == 0) {
00760       Record(Parameters());
00761     }
00762   }
00763 }
00764 
00765 /// Keep track of current parameter values
00766 ///
00767 /// \param p   Current parameter values
00768 ///
00769 /// If you're analysing a big model with lots of parameters, only some
00770 /// of which are of primary interest, you may want to override Record() to
00771 /// either keep track only of the few parameters that are of primary 
00772 /// interest, either discarding the others or writing them to disk.
00773 ///
00774 void
00775 Model::Record(const SampleVector& p) {
00776   results_.push_back(p);
00777   if (calculateLikelihood_) {
00778     likelihood_.Add(Llike(p));
00779   }
00780 }
00781 
00782 /// Produce a progress display
00783 ///
00784 /// If you're writing a sampler under a GUI and want a progress display,
00785 /// you'll definitely want to override this.
00786 ///
00787 void
00788 Model::InterimReport(std::ostream& outf, const std::string header, 
00789                      const int progress, const int goal) 
00790 {
00791   if (!pd_) {
00792     outf << endl << header;
00793     pd_ = new boost::progress_display(goal, outf);
00794   }
00795   ++(*pd_);
00796   if (progress == goal-1) {
00797     delete pd_;
00798     pd_ = 0;
00799   }
00800 }
00801 
00802 /// Produce a final report
00803 ///
00804 /// \param outf     The stream on which the report is to be written
00805 /// \param lastPar  -1 = all parameters, k+1 = k parameters 
00806 ///
00807 /// The report includes a header, the label for each parameter, and
00808 /// the posterior mean, standard deviation, 2.5%, 50%, and 97.5%tiles.
00809 ///
00810 void
00811 Model::Report(std::ostream& outf, const int lastPar) {
00812   ReportHead(outf);
00813   unsigned nPars = (lastPar < 0) ? results_[0].size() : lastPar;
00814   for (unsigned i = 0; i < nPars; ++i) {
00815     Summarize(i, outf);
00816   }
00817   ReportDic(outf);
00818 }
00819 
00820 /// Set the number of iterations in the burn-in period
00821 ///
00822 /// \param nBurnin   the number of burn-in iterations
00823 ///
00824 void
00825 Model::SetBurnIn(const int nBurnin) {
00826   nBurnin_ = nBurnin;
00827 }
00828 
00829 /// Set the number of iterations in the sample period
00830 ///
00831 /// \param nSample   the number of sample iterations
00832 ///
00833 void
00834 Model::SetSample(const int nSample) {
00835   nSample_ = nSample;
00836 }
00837 
00838 /// Set the thinning interval (the interval between saved samples)
00839 ///
00840 /// \parm thin   the thinning interval
00841 ///
00842 void
00843 Model::SetThin(const int thin) {
00844   nThin_ = thin;
00845 }
00846 
00847 /// Produce the report header
00848 ///
00849 /// \param outf The stream on which the report is being written
00850 /// 
00851 void
00852 Model::ReportHead(std::ostream& outf) {
00853   outf << "Posterior summary..." << endl
00854        << *summaryFormat_ 
00855     % "Parameter" % "Mean" % "s.d." % "2.5%" % "50%" % "97.5%" << endl;
00856   outf << *summaryFormat_
00857     % "---------" % "------------" % "------------" % "------------" 
00858     % "------------" % "------------" << endl;
00859 }
00860 
00861 /// Produce the summary statistics for each parameter
00862 ///
00863 /// \param i  Index of the parameter being reported on
00864 /// \param outf The stream on which the report is being written
00865 ///
00866 void
00867 Model::Summarize(const int i, std::ostream& outf) {
00868     int n = nSample_/nThin_;
00869     vector<double> x(n);
00870     for (int k = 0; k < n; ++k) {
00871       x[k] = any_cast<double>(results_[k][i]);
00872     }
00873     SimpleStatistic xStat(x);
00874     outf << *summaryFormat_ % Label(i)
00875       % xStat.Mean() % xStat.StdDev() % quantile(x, 0.025) 
00876       % quantile(x, 0.5) % quantile(x, 0.975) << endl;
00877 }
00878 
00879 /// Produce the parameter label
00880 ///
00881 /// \param i  Index of the parameter
00882 ///
00883 std::string 
00884 Model::Label(const int i) const {
00885   return step_[i]->Label();
00886 }
00887 
00888 
00889 /// Likelihood
00890 ///
00891 /// \param par  A vector of parameters from which to calculate the likelihood
00892 ///
00893 double
00894 Model::Llike(const SampleVector& par) const {
00895   return 0.0;
00896 }
00897 
00898 /// Calculate and report DIC statistics
00899 ///
00900 void
00901 Model::ReportDic(std::ostream& outf) {
00902   if (!calculateLikelihood_) {
00903     return;
00904   }
00905   SampleIter sTer = results_[0].begin();
00906   SampleIter sEnd = results_[0].end();
00907   SampleVector pMean(nElem_);
00908   if (useMedian_) {   // use posterior median for Dhat
00909     int n = results_.size();
00910     for (int j = 0; j < nElem_; ++j) {
00911       vector<double> x(n);
00912       for (int i = 0; i < n; ++i) {
00913         x[i] = any_cast<double>(results_[i][j]);
00914       }
00915       pMean[j] = quantile(x, 0.5);
00916     }
00917   } else {   // use posterior mean for Dhat (default)
00918     vector<SimpleStatistic> stats(nElem_);
00919     ResultsIter iTer = results_.begin();
00920     ResultsIter iEnd = results_.end();
00921     for (; iTer != iEnd; ++iTer) {
00922       SampleVector par(*iTer);
00923       SampleIter pTer = par.begin();
00924       SampleIter pEnd = par.end();
00925       for (unsigned j = 0; j < nElem_; ++j) {
00926         stats[j].Add(any_cast<double>(par[j]));
00927       }
00928     }
00929     for (unsigned j = 0; j < nElem_; ++j) {
00930       pMean[j] = stats[j].Mean();
00931     }
00932   }
00933   double Dbar = -2.0*likelihood_.Mean();
00934   double Dhat = -2.0*Llike(pMean);
00935   double pD = Dbar - Dhat;
00936   double DIC = Dbar + pD;
00937   outf << dic_ % "---------" % "------------" << endl;
00938   outf << dic_ % "Dbar" % Dbar << endl;
00939   outf << dic_ % "Dhat" % Dhat << endl;
00940   if (0) {
00941     // deviance = -2*likelihood
00942     // var(deviance) = 4*var(likelihood)
00943     // pD2 = (1/2)var(deviance) -- Gelman et al., 2nd edition, p. 182
00944     double pD2 = 2.0*likelihood_.Variance();
00945     outf << dic_ % "pD(1)" % pD << endl;
00946     outf << dic_ % "pD(2)" % pD2 << endl;
00947   } else {
00948     outf << dic_ % "pD" % pD << endl;
00949   }
00950   outf << dic_ % "DIC" % DIC << endl;
00951 }
00952 
00953 /// percent -- integer/integer
00954 ///
00955 /// \param k  Count
00956 /// \param n  Sample size
00957 ///
00958 double 
00959 Model::percent(const int k, const int n) const {
00960   return 100.0*static_cast<double>(k)/n;
00961 }
00962 
00963 /// percent -- average percent across a vector
00964 ///
00965 /// \param x  Vector of counts
00966 /// \param n  Sample size
00967 ///
00968 double 
00969 Model::percent(const std::vector<int>& x, const int n) const {
00970   int nElem = x.size();
00971   SimpleStatistic pStat;
00972   for (int i = 0; i < nElem; ++i) {
00973     pStat.Add(percent(x[i], n));
00974   }
00975   return pStat.Mean();
00976 }
00977 
00978 /// percent -- average percent across a vector of vectors
00979 ///
00980 /// \param x  Vector of vector of counts
00981 /// \param n  Sample size
00982 ///
00983 double 
00984 Model::percent(const std::vector<std::vector<int> >& x, const int n) const {
00985   int nRows = x.size();
00986   SimpleStatistic pStat;
00987   for (int i = 0; i < nRows; ++i) {
00988     int nCols = x[i].size();
00989     for (int j = 0; j < nCols; ++j) {
00990       pStat.Add(percent(x[i][j], n));
00991     }
00992   }
00993   return pStat.Mean();
00994 }
00995 
00996 void
00997 Model::Reset(void) {
00998   ModelSteps::const_iterator i = step_.begin();
00999   ModelSteps::const_iterator iEnd = step_.end();
01000   for (; i != iEnd; ++i) {
01001     (*i)->ResetAccept();
01002   }
01003 }
01004 
01005 void
01006 Model::Generation(void) {
01007   ModelSteps::const_iterator i = step_.begin();
01008   ModelSteps::const_iterator iEnd = step_.end();
01009   for (; i != iEnd; ++i) {
01010     (*i)->DoStep();
01011   }
01012 }
01013 
01014 /// Return parameter vector associated with this step
01015 ///
01016 /// Values in the sample vector are stored as boost::any. Retrieving them
01017 /// will require an appropriate boost::any_cast<>
01018 ///
01019 SampleVector
01020 Model::Parameters(void) const {
01021   SampleVector x;
01022   ModelSteps::const_iterator i = step_.begin();
01023   ModelSteps::const_iterator iEnd = step_.end();
01024   for (; i != iEnd; ++i) {
01025     x.push_back((*i)->aValue());
01026   }
01027   return x;
01028 }
01029 

Generated on Tue Mar 27 16:03:38 2007 for mcmc by  doxygen 1.5.1