tristanz / ScytheMCMC (http://bytebucket.org/tristanz/scythemcmc/wiki/html/index.html)
A Scythe Markov Chain Monte Carlo C++ Framework
Clone this repository (size: 1.0 MB): HTTPS / SSH
$ hg clone http://bitbucket.org/tristanz/scythemcmc
| commit 7: | 009eb2e96f0a |
| parent 6: | 327b365c0e1a |
| branch: | default |
Doc cleanup.
Changed (Δ516 bytes):
raw changeset »
src/mcmc.h (88 lines added, 85 lines removed)
1 |
/* |
|
1 |
/*! \mainpage |
|
2 |
2 |
|
3 |
3 |
<table> |
4 |
4 |
<tr><th>Library <td>Scythe MCMC - A Scythe Markov Chain Monte Carlo C++ Framework |
7 |
7 |
<tr><th>Version <td>0.1 |
8 |
8 |
</table> |
9 |
9 |
|
10 |
|
|
10 |
\section intro INTRODUCTION |
|
11 |
11 |
|
12 |
12 |
Scythe MCMC is a C++ header library that eases the development of Markov Chain Monte Carlo (MCMC). It is based on the |
13 |
13 |
<a href="http://scythe.wustl.edu/">Scythe Statistical Library</a>. |
38 |
38 |
allows development of models that cannot be sampled effectively using either Bugs or Jags, such |
39 |
39 |
nonparametric Bayesian models without truncation approximations. |
40 |
40 |
|
41 |
|
|
41 |
\section features FEATURES |
|
42 |
42 |
|
43 |
43 |
- Based on the <a href="http://scythe.wustl.edu/">Scythe Statistical Library</a>. |
44 |
44 |
- Eliminates commandline and option parsing boilerplate code using |
53 |
53 |
- Slice sampler for Dirichlet Process and Indian Buffet Process. |
54 |
54 |
- MIT License. |
55 |
55 |
|
56 |
|
|
56 |
\section gettingstarted GETTING STARTED |
|
57 |
57 |
|
58 |
58 |
|
59 |
|
|
59 |
\section license MIT LICENSE |
|
60 |
60 |
|
61 |
61 |
The license text below is the boilerplate "MIT License" used from: |
62 |
62 |
http://www.opensource.org/licenses/mit-license.php |
| … | … | @@ -121,9 +121,7 @@ double iInf = std::numeric_limits<int>:: |
121 |
121 |
mersenne myrng; |
122 |
122 |
|
123 |
123 |
|
124 |
// |
|
125 |
||
126 |
/* |
|
124 |
/*! Basic MCMC options. |
|
127 |
125 |
* These options are generally specified at the command line and are generic to all |
128 |
126 |
* MCMC samplers. Other options are passed through an .ini config file. |
129 |
127 |
*/ |
| … | … | @@ -147,10 +145,10 @@ struct MCMCOptions { |
147 |
145 |
/// around everwhere. |
148 |
146 |
MCMCOptions mcmc_options; |
149 |
147 |
|
150 |
/* |
|
148 |
/*! Check if file exists. |
|
151 |
149 |
Source: http://www.techbytes.ca/techbyte103.html |
152 |
@param strFilename Filename to check. |
|
153 |
@returns True is file exists. False otherwise. |
|
150 |
\param strFilename Filename to check. |
|
151 |
\returns True is file exists. False otherwise. |
|
154 |
152 |
*/ |
155 |
153 |
bool FileExists(string strFilename) { |
156 |
154 |
struct stat stFileInfo; |
| … | … | @@ -176,7 +174,7 @@ bool FileExists(string strFilename) { |
176 |
174 |
return(blnReturn); |
177 |
175 |
} |
178 |
176 |
|
179 |
/* |
|
177 |
/*! Shows command line usage. |
|
180 |
178 |
Diplays: |
181 |
179 |
<pre> |
182 |
180 |
ScytheMCMC v. 0.1 |
| … | … | @@ -210,7 +208,7 @@ void ShowUsage() { |
210 |
208 |
<< "\t --burnin=0 --thin=1 --random-seed=12345" << endl << endl; |
211 |
209 |
} |
212 |
210 |
|
213 |
/* |
|
211 |
/*! Parses command line options. |
|
214 |
212 |
Parses and stores command line options and stores them in MCMCOptions instance |
215 |
213 |
mcmc_options. Initializes random mersenne instance myrng. |
216 |
214 |
@see ShowUsage. |
| … | … | @@ -318,7 +316,7 @@ void DefaultStartUp(int argc, char* argv |
318 |
316 |
} |
319 |
317 |
|
320 |
318 |
|
321 |
/* |
|
319 |
/*! Main parameter class. |
|
322 |
320 |
* The model is defined as many instances of parameter subclasses. Different Step types require different methods |
323 |
321 |
* to be implemented in each Parameter subclass. |
324 |
322 |
* |
| … | … | @@ -398,47 +396,47 @@ class Parameter { |
398 |
396 |
public: |
399 |
397 |
/// Default class constructor. |
400 |
398 |
Parameter() {} |
401 |
/* |
|
399 |
/*! Base class constructor |
|
402 |
400 |
* |
403 |
* @param track True if parameter should be tracked and saved. |
|
404 |
* @param label Label of parameter for tracking purposes. |
|
401 |
* \param track True if parameter should be tracked and saved. |
|
402 |
* \param label Label of parameter for tracking purposes. |
|
405 |
403 |
*/ |
406 |
404 |
Parameter(bool track, string label) : track_(track), label_(label) {} |
407 |
405 |
|
408 |
406 |
/// Function for deterministic nodes. |
409 |
/// |
|
407 |
/// \return Function value. |
|
410 |
408 |
virtual double Function() { return 0.0; }; |
411 |
409 |
|
412 |
410 |
/// Starting value. |
413 |
/// |
|
411 |
/// \return Starting value. |
|
414 |
412 |
virtual double StartingValue() { return 0.0; }; |
415 |
413 |
|
416 |
414 |
/// Log of the probability density (plus constant) |
417 |
/// @param value Value of parameter to evaluate density at. |
|
418 |
/// @return Log of probability density (plus constant) |
|
415 |
/// \param value Value of parameter to evaluate density at. |
|
416 |
/// \return Log of probability density (plus constant) |
|
419 |
417 |
virtual double LogDensity(double value) { return 0.0; } |
420 |
418 |
|
421 |
419 |
/// Return a random draw from the posterior. |
422 |
420 |
/// Random draw from posterior is called by GibbsStep. |
423 |
/// |
|
421 |
/// \return Random draw from posterior. |
|
424 |
422 |
virtual double RandomPosterior() { return 0.0; } |
425 |
423 |
|
426 |
424 |
/// Value of parameter. |
427 |
/// |
|
425 |
/// \return Parameter value |
|
428 |
426 |
virtual double Value() { return 0.0; }; |
429 |
427 |
|
430 |
428 |
/// Save a new value of the parameter. |
431 |
/// |
|
429 |
/// \param new_value New value to save. |
|
432 |
430 |
virtual void Save(double new_value) {}; |
433 |
431 |
|
434 |
432 |
/// Parameter is tracked / saved. |
435 |
/// |
|
433 |
/// \return True if parameter is tracked. |
|
436 |
434 |
bool Track() { |
437 |
435 |
return track_; |
438 |
436 |
} |
439 |
437 |
|
440 |
438 |
/// String label of parameter. |
441 |
/// |
|
439 |
/// \return Label of parameter, for purposes of saving output. |
|
442 |
440 |
string Label() { |
443 |
441 |
return label_; |
444 |
442 |
} |
| … | … | @@ -450,7 +448,7 @@ private: |
450 |
448 |
}; |
451 |
449 |
|
452 |
450 |
|
453 |
/* |
|
451 |
/*! Base step class. |
|
454 |
452 |
* The step (Gibbs, Metropolis-Hastings, Slice, etc) describes how the sampler |
455 |
453 |
* calculates the next value of each parameter. The key function is Step::DoStep, which is |
456 |
454 |
* equivalent to the Execute function in a <a href="http://en.wikipedia.org/wiki/Command_pattern">Command Pattern</a>. |
| … | … | @@ -460,32 +458,32 @@ private: |
460 |
458 |
*/ |
461 |
459 |
class Step { |
462 |
460 |
public: |
463 |
/* |
|
461 |
/*! Take step. |
|
464 |
462 |
* Executes the main step function, such as taking a MH step or deterministic step. |
465 |
463 |
*/ |
466 |
464 |
virtual void DoStep() {} |
467 |
/* |
|
465 |
/*! Set starting value. |
|
468 |
466 |
* Calls the parameter's Parameter::Starting function and then saves the result using Parameter::Save. |
469 |
467 |
*/ |
470 |
468 |
virtual void Start() {} |
471 |
469 |
|
472 |
470 |
/// Return parameter value |
473 |
/// |
|
471 |
/// \return The value of the parameter associated with the step instance. |
|
474 |
472 |
/// @see Parameter::Value |
475 |
473 |
virtual double ParameterValue() { return 0.0; } |
476 |
474 |
|
477 |
475 |
/// Return parameter label |
478 |
/// |
|
476 |
/// \return The label of the parameter associated with the step instance. |
|
479 |
477 |
/// @see Parameter::Label |
480 |
478 |
virtual string ParameterLabel() { return ""; } |
481 |
479 |
|
482 |
480 |
/// Return the tracking status |
483 |
/// |
|
481 |
/// \return The tracking status of the parameter associated with the step instance. |
|
484 |
482 |
/// @see Parameter::Track |
485 |
483 |
virtual bool ParameterTrack() { return true; } |
486 |
484 |
}; |
487 |
485 |
|
488 |
/* |
|
486 |
/*! Gibbs step. |
|
489 |
487 |
* A univariate Gibbs step draws from the Parameter::RandomPosterior function of a Parameter and then saves the result |
490 |
488 |
* using Parameter:Save. |
491 |
489 |
*/ |
| … | … | @@ -494,12 +492,12 @@ class GibbsStep: public Step { |
494 |
492 |
public: |
495 |
493 |
/// Default constructor, for copy assignments, etc. |
496 |
494 |
GibbsStep() {} |
497 |
/** Main constructor taking a Parameter object. |
|
498 |
* @param parameter A Parameter that implements Parameter::RandomPosterior. |
|
495 |
/*! Main constructor taking a Parameter object. |
|
496 |
* \param parameter A Parameter that implements Parameter::RandomPosterior. |
|
499 |
497 |
*/ |
500 |
498 |
GibbsStep(ParameterType parameter) : parameter_(parameter) { |
501 |
499 |
} |
502 |
/* |
|
500 |
/*! Take a Gibbs step for the parameter. |
|
503 |
501 |
* Draws from the parameter's Parameter::RandomPosterior function and then saves the result using Parameter::Save. |
504 |
502 |
*/ |
505 |
503 |
void DoStep() { |
| … | … | @@ -526,7 +524,7 @@ private: |
526 |
524 |
ParameterType parameter_; |
527 |
525 |
}; |
528 |
526 |
|
529 |
/* |
|
527 |
/*! Deterministic function step. |
|
530 |
528 |
* Deterministic nodes can be helpful to track summary statistics or to reduce computations through intermediate use |
531 |
529 |
* of sufficient statistics across multiple parameters. FunctionStep calls the parameters Parameter::Function method |
532 |
530 |
* and saves the result using Parameter::Save. |
| … | … | @@ -536,20 +534,20 @@ class FunctionStep: public Step { |
536 |
534 |
public: |
537 |
535 |
/// Default constructor, for copy assignments, etc. |
538 |
536 |
FunctionStep() {} |
539 |
/** Main constructor taking a Parameter object. |
|
540 |
* @param parameter A Parameter that implements Parameter::Function. |
|
537 |
/*! Main constructor taking a Parameter object. |
|
538 |
* \param parameter A Parameter that implements Parameter::Function. |
|
541 |
539 |
*/ |
542 |
540 |
FunctionStep(ParameterType parameter) : parameter_(parameter) { |
543 |
541 |
} |
544 |
/* |
|
542 |
/*! Take a function step for the parameter. |
|
545 |
543 |
* Calculates the value of Parameter::Function and then saves the result using Parameter::Save. |
546 |
544 |
*/ |
547 |
545 |
void DoStep() { |
548 |
546 |
parameter_.Save(parameter_.Function()); |
549 |
547 |
} |
550 |
548 |
|
551 |
/** Set function step starting value. |
|
552 |
* \remark Because the starting value uses the normal function calculation, it is important to add |
|
549 |
/*! Set function step starting value. |
|
550 |
* \note Because the starting value uses the normal function calculation, it is important to add |
|
553 |
551 |
* parameters in an order that makes the function feasible. StartingValue functions are called in the order |
554 |
552 |
* they are added. Any implemention of a StartingValue method for a FunctionStep will not be used. |
555 |
553 |
*/ |
| … | … | @@ -574,26 +572,26 @@ private: |
574 |
572 |
}; |
575 |
573 |
|
576 |
574 |
|
577 |
/* |
|
575 |
/*! Normal proposal for MH. |
|
578 |
576 |
* Normal proposal draws from N(starting_value, standard_deviation). |
579 |
577 |
*/ |
580 |
578 |
class NormalProposal { |
581 |
579 |
public: |
582 |
580 |
NormalProposal() {} |
583 |
/* |
|
581 |
/*! Constructor |
|
584 |
582 |
* \param standard_deviation MH tuning parameter for normal model |
585 |
583 |
*/ |
586 |
584 |
NormalProposal(double standard_deviation) : standard_deviation_(standard_deviation) {} |
587 |
585 |
|
588 |
/* |
|
586 |
/*! Draw from normal proposal |
|
589 |
587 |
* \param starting_value Starting value. |
590 |
588 |
*/ |
591 |
589 |
double Draw(double starting_value) { |
592 |
590 |
return myrng.rnorm(starting_value, standard_deviation_); |
593 |
591 |
} |
594 |
592 |
|
595 |
/** Log probability of proposal new value, given starting value. |
|
596 |
* \remark Needs to be implemented but can be 0.0 if proposal is symmetric, which it is. |
|
593 |
/*! Log probability of proposal new value, given starting value. |
|
594 |
* \note Needs to be implemented but can be 0.0 if proposal is symmetric, which it is. |
|
597 |
595 |
* \param starting_value Starting value. |
598 |
596 |
* \param new_value Proposed new value. |
599 |
597 |
*/ |
| … | … | @@ -606,7 +604,7 @@ private: |
606 |
604 |
}; |
607 |
605 |
|
608 |
606 |
|
609 |
/* |
|
607 |
/*! Metropolis Hastings step |
|
610 |
608 |
* Basic univariate Metropolis-Hastings step. Requires both a Parameter and Proposal instance. |
611 |
609 |
*/ |
612 |
610 |
template <typename ParameterType, typename ProposalType> |
| … | … | @@ -614,13 +612,13 @@ class MetropStep: public Step { |
614 |
612 |
public: |
615 |
613 |
/// Default constructor, for copy assignments, etc. |
616 |
614 |
MetropStep() {} |
617 |
/** Main constructor taking a Parameter and Proposal object. |
|
618 |
* @param parameter A Parameter that implements Parameter::LogDensity |
|
619 |
|
|
615 |
/*! Main constructor taking a Parameter and Proposal object. |
|
616 |
* \param parameter A Parameter that implements Parameter::LogDensity |
|
617 |
* \param proposal A Proposal instance that implements Proposal::LogDensity and Proposal::Draw. |
|
620 |
618 |
*/ |
621 |
619 |
MetropStep(ParameterType parameter, ProposalType proposal) : parameter_(parameter), proposal_(proposal) {} |
622 |
620 |
|
623 |
/* |
|
621 |
/*! Take a function step for the parameter. |
|
624 |
622 |
* Calculates the value of Parameter::Function and then saves the result using Parameter::Save. |
625 |
623 |
*/ |
626 |
624 |
void DoStep() { |
| … | … | @@ -656,28 +654,36 @@ private: |
656 |
654 |
ProposalType proposal_; |
657 |
655 |
}; |
658 |
656 |
|
659 |
/** Univariate slice sampling step. |
|
660 |
* Basic univariate slice sampling step step. |
|
661 |
* \remark See Neal (2003) "Slice Sampling" Annals of Statistics. |
|
662 |
* \remark Code based on Neal's R code (March 17, 2008): http://www.cs.toronto.edu/~radford/ftp/slice-R-prog |
|
663 |
* \remark With poor initial values or choice of w, the Slice Sampler can get take a very very long time to fine |
|
664 |
* a suitable slice. This may appear like a crash. Experimenting with w may speed sampling. |
|
657 |
/*! \brief Univariate slice sampling step. |
|
658 |
* Basic univariate slice sampling step with stepping out and shrinkage. Performs a slice sampling update from an initial |
|
659 |
* point to a new point that leaves invariant the distribution with the specifified log density functions |
|
660 |
* |
|
661 |
* The log desnity function may return -Inf for points outside the support of the distribution. |
|
662 |
* If a lower and/or upper bound is specified for the support, the log density function will not be called outside |
|
663 |
* such limits. |
|
664 |
* |
|
665 |
* \note See Neal, R. M (2003) "Slice Sampling" (with discussion), <i>Annals of Statistics</i>, |
|
666 |
* vol. 31, no. 3, pp. 705-767. |
|
667 |
* \note Code and description based on Neal's R code (March 17, 2008): http://www.cs.toronto.edu/~radford/ftp/slice-R-prog |
|
668 |
* \note With poor initial values or choice of w, slice sampling can get take a very very long time to find |
|
669 |
* a suitable slice. This may appear like a crash. Experimenting with w may speed sampling, but things tends |
|
670 |
* to work pretty well with default values in many cases. |
|
665 |
671 |
*/ |
666 |
672 |
template <typename ParameterType> |
667 |
673 |
class SliceStep: public Step { |
668 |
674 |
public: |
669 |
675 |
/// Default constructor, for copy assignments, etc. |
670 |
676 |
SliceStep() {} |
671 |
/** Main constructor. |
|
672 |
* @param parameter A Parameter that implements Parameter::LogDensity |
|
673 |
* @param w Size of the steps for creating interval (default = 1) |
|
674 |
* @param lower Lower bound on the support of the distribution (default = -Infinity) |
|
675 |
|
|
677 |
/*! Main constructor for slice sampling step. |
|
678 |
* \param parameter A Parameter that implements Parameter::LogDensity |
|
679 |
* \param w Size of the steps for creating interval (default = 1) |
|
680 |
* \param lower Lower bound on the support of the distribution (default = -Infinity) |
|
681 |
* \param upper Upper bound on the support of the distribution (default = Infinity) |
|
676 |
682 |
*/ |
677 |
683 |
SliceStep(ParameterType parameter, double w = 1.0, double lower=-dInf, double upper=dInf) : |
678 |
684 |
parameter_(parameter), w_(w), lower_(lower), upper_(upper) {} |
679 |
685 |
|
680 |
/* |
|
686 |
/*! Take a slice sampling step for the parameter. |
|
681 |
687 |
*/ |
682 |
688 |
void DoStep() { |
683 |
689 |
// Find the log density at the initial point. |
| … | … | @@ -705,7 +711,6 @@ public: |
705 |
711 |
break; |
706 |
712 |
} |
707 |
713 |
L = L - w_; |
708 |
//cout << "a" << endl; |
|
709 |
714 |
} |
710 |
715 |
|
711 |
716 |
while(true) { |
| … | … | @@ -716,7 +721,6 @@ public: |
716 |
721 |
break; |
717 |
722 |
} |
718 |
723 |
R = R + w_; |
719 |
// cout << "b" << endl; |
|
720 |
724 |
} |
721 |
725 |
|
722 |
726 |
// Shrink interval to lower and upper bounds. |
| … | … | @@ -742,7 +746,6 @@ public: |
742 |
746 |
else { |
743 |
747 |
L = x1; |
744 |
748 |
} |
745 |
// cout << "c" << endl; |
|
746 |
749 |
} |
747 |
750 |
|
748 |
751 |
// Save the point sampled |
| … | … | @@ -773,19 +776,19 @@ private: |
773 |
776 |
double upper_; |
774 |
777 |
}; |
775 |
778 |
|
776 |
/* |
|
779 |
/*! \brief MCMC sampler. |
|
777 |
780 |
* The sampler is the main MCMC object that holds all the MCMC steps for each parameter. Running the sampler |
778 |
781 |
* performs MCMC sampling for the model, saving results, and displaying progress. In the language of the Command Pattern, the |
779 |
782 |
* sampler is the Invoker or Command Manager. |
780 |
783 |
* |
781 |
* After instantiating the sampler, users should add all the required steps using the Sampler::AddStep method, which adds places |
|
782 |
* each step onto a stack. The sampling process can be run using Sampler::Run. |
|
784 |
* After instantiating the sampler, users should add all the required steps using the Sampler::AddStep method, which places |
|
785 |
* each step onto a stack. The entire sampling process is run using Sampler::Run. |
|
783 |
786 |
*/ |
784 |
787 |
class Sampler { |
785 |
788 |
public: |
786 |
/** Constructor to initialize sampler. |
|
787 |
* @param options MCMC options object that defines sample_size, burnin, thinning interval, etc. |
|
788 |
|
|
789 |
/*! \beif Constructor to initialize sampler. |
|
790 |
* \param options MCMC options object that defines sample_size, burnin, thinning interval, etc. |
|
791 |
*/ |
|
789 |
792 |
Sampler(MCMCOptions options) { |
790 |
793 |
cout << "Creating Sampler... " << endl; |
791 |
794 |
sample_size_ = options.sample_size; |
| … | … | @@ -793,11 +796,11 @@ public: |
793 |
796 |
thin_ = options.thin; |
794 |
797 |
out_file_ = options.out_file; |
795 |
798 |
} |
796 |
/* |
|
799 |
/*! \brief Add Step to Sampler execution stack. |
|
797 |
800 |
* All parameters should have an associated Step that is added to the sampler. The sampler stack |
798 |
801 |
* defines one sampler iteration. |
799 |
* @param step Step object for a given parameter. |
|
800 |
**/ |
|
802 |
* \param step Step object for a given parameter. |
|
803 |
*/ |
|
801 |
804 |
void AddStep(Step* step) { |
802 |
805 |
// Add step to step stack. |
803 |
806 |
steps_.push_back(step); |
| … | … | @@ -806,9 +809,9 @@ public: |
806 |
809 |
tracks_.push_back(steps_.size() - 1); |
807 |
810 |
} |
808 |
811 |
} |
809 |
/** Run sampler for a specific number of iterations. |
|
810 |
* @param number_of_iterations Number of iterations to run sampler. |
|
811 |
|
|
812 |
/*! Run sampler for a specific number of iterations. |
|
813 |
* \param number_of_iterations Number of iterations to run sampler. |
|
814 |
* \param progress Display a progress bar. |
|
812 |
815 |
*/ |
813 |
816 |
void Iterate(int number_of_iterations, bool progress = false) { |
814 |
817 |
if(progress) { |
| … | … | @@ -828,7 +831,7 @@ public: |
828 |
831 |
} |
829 |
832 |
} |
830 |
833 |
} |
831 |
/* |
|
834 |
/*! Run sampler. |
|
832 |
835 |
* Run the MCMC sampling procedure, including burning in, sampling, thinning, displaying progress, |
833 |
836 |
* and saving results. |
834 |
837 |
*/ |
| … | … | @@ -889,14 +892,14 @@ public: |
889 |
892 |
|
890 |
893 |
cout << "Total elapsed time: " << timer.elapsed() << " seconds" << endl; |
891 |
894 |
} |
892 |
/** Number of steps in one sampler iteration. |
|
893 |
* @return Number of steps. |
|
895 |
/*! Number of steps in one sampler iteration. |
|
896 |
* \return Number of steps. |
|
894 |
897 |
*/ |
895 |
898 |
int NumberOfSteps() { |
896 |
899 |
return steps_.size(); |
897 |
900 |
} |
898 |
/** Number of tracked steps in one sampler iteration. |
|
899 |
* @return Number of tracked steps. |
|
901 |
/*! Number of tracked steps in one sampler iteration. |
|
902 |
* \return Number of tracked steps. |
|
900 |
903 |
*/ |
901 |
904 |
int NumberOfTrackedSteps() { |
902 |
905 |
return tracks_.size(); |
| … | … | @@ -910,7 +913,7 @@ private: |
910 |
913 |
vector<int> tracks_; |
911 |
914 |
}; |
912 |
915 |
|
913 |
/* |
|
916 |
/*! Approximately equal. |
|
914 |
917 |
* Checks if two doubles are within the numeric_limits<double>::epsilon() precision of each other. |
915 |
918 |
* Useful if === is too strict. |
916 |
919 |
*/ |
