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.
Tristan Zajonc / tristanz
14 months ago

Changed (Δ516 bytes):

raw changeset »

src/mcmc.h (88 lines added, 85 lines removed)

Up to file-list src/mcmc.h:

1
/** @mainpage
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
    @section intro INTRODUCTION
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
    @section features FEATURES
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
    @section gettingstarted GETTING STARTED
56
    \section gettingstarted GETTING STARTED
57
57
    
58
58
59
    @section license MIT LICENSE
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
/** Basic MCMC options.
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
/** Check if file exists.
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
/** Shows command line usage.
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
/** Parses command line options.
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
/** Main parameter class. 
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
  /** Base class constructor
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
  /// @return Function value.
407
  /// \return Function value.
410
408
  virtual double Function() { return 0.0; };
411
409
  
412
410
  /// Starting value.
413
  /// @return Starting value.
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
  /// @return Random draw from posterior.
421
  /// \return Random draw from posterior.
424
422
  virtual double RandomPosterior() { return 0.0; }
425
423
  
426
424
  /// Value of parameter.
427
  /// @return Parameter value
425
  /// \return Parameter value
428
426
  virtual double Value() { return 0.0; };
429
427
430
428
  /// Save a new value of the parameter.
431
  /// @param new_value New value to save.
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
  /// @return True if parameter is tracked.
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
  /// @return Label of parameter, for purposes of saving output.
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
/** Base step class.
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
  /** Take step.
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
  /** Set starting value.
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
  /// @return The value of the parameter associated with the step instance.
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
  /// @return The label of the parameter associated with the step instance.
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
  /// @return The tracking status of the parameter associated with the step instance.
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
/** Gibbs step.
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
  /** Take a Gibbs step for the parameter.
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
/** Deterministic function step.
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
  /** Take a function step for the parameter.
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
/** Normal proposal for MH.
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
  /** Constructor
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
  /** Draw from normal proposal
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
/** Metropolis Hastings step
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
   *  @param proposal A Proposal instance that implements Proposal::LogDensity and Proposal::Draw.
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
  /** Take a function step for the parameter.
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
   *  @param upper Upper bound on the support of the distribution (default = Infinity)
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
  /** Take a slice sampling step for the parameter.
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
/** Main MCMC sampler.
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
  /** Add Step to Sampler execution stack.
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
   * @param progress Display a progress bar.
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
  /** Run sampler.
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
/** Approximately equal.
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
 */