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 8: f3d19d045528
parent 7: 009eb2e96f0a
branch: default
Added log normal and beta proposals types
Tristan Zajonc / tristanz
14 months ago

Changed (Δ4.5 KB):

raw changeset »

Doxyfile (2 lines added, 2 lines removed)

src/mcmc.h (247 lines added, 69 lines removed)

Up to file-list Doxyfile:

@@ -27,12 +27,12 @@ FULL_PATH_NAMES = YES
27
27
STRIP_FROM_PATH        = /Users/tristanz/Data/OpenIRT/ScytheMCMC/src
28
28
STRIP_FROM_INC_PATH    = 
29
29
SHORT_NAMES            = NO
30
JAVADOC_AUTOBRIEF      = YES
30
JAVADOC_AUTOBRIEF      = NO
31
31
QT_AUTOBRIEF           = NO
32
32
MULTILINE_CPP_IS_BRIEF = NO
33
33
INHERIT_DOCS           = YES
34
34
SEPARATE_MEMBER_PAGES  = NO
35
TAB_SIZE               = 8
35
TAB_SIZE               = 4
36
36
ALIASES                = 
37
37
OPTIMIZE_OUTPUT_FOR_C  = NO
38
38
OPTIMIZE_OUTPUT_JAVA   = NO

Up to file-list src/mcmc.h:

@@ -121,7 +121,8 @@ double iInf = std::numeric_limits<int>::
121
121
mersenne myrng; 
122
122
123
123
124
/*! Basic MCMC options.
124
/*! \brief Basic MCMC options.
125
 *
125
126
 * These options are generally specified at the command line and are generic to all
126
127
 * MCMC samplers.  Other options are passed through an .ini config file.
127
128
 */
@@ -145,10 +146,11 @@ struct MCMCOptions {
145
146
/// around everwhere.
146
147
MCMCOptions mcmc_options;
147
148
148
/*! Check if file exists.
149
  Source: http://www.techbytes.ca/techbyte103.html
149
/*! \brief Check if file exists.
150
 *
150
151
  \param strFilename Filename to check.
151
152
  \returns True is file exists. False otherwise.
153
  \note Source: http://www.techbytes.ca/techbyte103.html.
152
154
 */
153
155
bool FileExists(string strFilename) {
154
156
  struct stat stFileInfo;
@@ -174,7 +176,8 @@ bool FileExists(string strFilename) {
174
176
  return(blnReturn);
175
177
}
176
178
177
/*! Shows command line usage.
179
/*! \brief Shows command line usage.
180
178
181
   Diplays:
179
182
<pre>
180
183
   ScytheMCMC v. 0.1
@@ -208,12 +211,13 @@ void ShowUsage() {
208
211
       << "\t   --burnin=0 --thin=1 --random-seed=12345" << endl << endl;
209
212
}
210
213
211
/*! Parses command line options.
214
/*! \brief Parses command line options.
215
212
216
  Parses and stores command line options and stores them in MCMCOptions instance
213
217
  mcmc_options.  Initializes random mersenne instance myrng.
214
  @see ShowUsage.
215
  @see mcmc_options.
216
  @see myrng.
218
  \see ShowUsage.
219
  \see mcmc_options.
220
  \see myrng.
217
221
*/
218
222
void DefaultStartUp(int argc, char* argv[]) {
219
223
  cout << "ScytheMCMC v. " << SCYTHE_MCMC_VERSION << endl << endl;
@@ -316,7 +320,8 @@ void DefaultStartUp(int argc, char* argv
316
320
}
317
321
318
322
319
/*! Main parameter class. 
323
/*! \brief Main parameter class. 
324
 *
320
325
 * The model is defined as many instances of parameter subclasses.  Different Step types require different methods
321
326
 * to be implemented in each Parameter subclass.
322
327
 *
@@ -396,7 +401,7 @@ class Parameter {
396
401
public:
397
402
  /// Default class constructor.
398
403
  Parameter() {}
399
  /*! Base class constructor
404
  /*! \brief Base class constructor
400
405
   *
401
406
   * \param track True if parameter should be tracked and saved.
402
407
   * \param label Label of parameter for tracking purposes.
@@ -447,43 +452,69 @@ private:
447
452
  string label_;
448
453
};
449
454
455
/*! \defgroup steps Implemented MCMC Step Types
456
 *
457
 * MCMC algorithms typically consist of many steps.  While users will often want
458
 * to implement their own step types, Scythe MCMC has implemented several that arise
459
 * over and over.  MetropStep and SliceStep in particular only require specification of
460
 * a log density function (minus an unknown constant).
461
 *
462
 */
450
463
451
/*! Base step class.
464
/*! \brief Base step class.
465
 *
466
 * \ingroup steps
467
 *
452
468
 * The step (Gibbs, Metropolis-Hastings, Slice, etc) describes how the sampler 
453
469
 * calculates the next value of each parameter.  The key function is Step::DoStep, which is
454
470
 * equivalent to the Execute function in a <a href="http://en.wikipedia.org/wiki/Command_pattern">Command Pattern</a>.
455
471
 * Samplers consists of a many of steps.
456
 * @see GibbsStep
457
 * @see Sampler
472
 *
473
 * \see GibbsStep
474
 * \see FunctionStep
475
 * \see MetropStep
476
 * \see SliceStep
477
 * \see Sampler
458
478
 */
459
479
class Step {
460
480
public:
461
  /*! Take step.
481
  /*! \brief Take step.
482
   *
462
483
   * Executes the main step function, such as taking a MH step or deterministic step.
463
484
   */ 
464
485
  virtual void DoStep() {}
465
  /*! Set starting value.
486
  /*! \brief Set starting value.
487
   *
466
488
   *  Calls the parameter's Parameter::Starting function and then saves the result using Parameter::Save.
467
489
   */
468
490
  virtual void Start() {}
469
491
  
470
  /// Return parameter value
471
  /// \return The value of the parameter associated with the step instance.
472
  /// @see Parameter::Value
492
  /*! \brief Return parameter value
493
   *
494
   * \return The value of the parameter associated with the step instance.
495
   * \see Parameter::Value
496
   */
473
497
  virtual double ParameterValue() { return 0.0; }
474
498
  
475
  /// Return parameter label
476
  /// \return The label of the parameter associated with the step instance.
477
  /// @see Parameter::Label
499
  /*! \brief Return parameter label
500
   *
501
   * \return The label of the parameter associated with the step instance.
502
   * \see Parameter::Label
503
   */
478
504
  virtual string ParameterLabel() { return ""; }
479
505
480
  /// Return the tracking status
481
  /// \return The tracking status of the parameter associated with the step instance.
482
  /// @see Parameter::Track
506
  /*! Return the tracking status
507
   *
508
   * \return The tracking status of the parameter associated with the step instance.
509
   * \see Parameter::Track
510
   */
483
511
  virtual bool ParameterTrack() { return true; }
484
512
};
485
513
486
/*! Gibbs step.
514
/*! \brief Gibbs step.
515
 *
516
 * \ingroup steps
517
 *
487
518
 * A univariate Gibbs step draws from the Parameter::RandomPosterior function of a Parameter and then saves the result
488
519
 * using Parameter:Save. 
489
520
 */
@@ -492,12 +523,13 @@ class GibbsStep: public Step {
492
523
public:
493
524
  /// Default constructor, for copy assignments, etc.
494
525
  GibbsStep() {}
495
  /*! Main constructor taking a Parameter object.
526
  /*! \brief Main constructor taking a Parameter object.
496
527
   *  \param parameter A Parameter that implements Parameter::RandomPosterior.
497
528
   */
498
529
  GibbsStep(ParameterType parameter) : parameter_(parameter) {
499
530
  }
500
  /*! Take a Gibbs step for the parameter.
531
  /*! \brief Take a Gibbs step for the parameter.
532
   *
501
533
   *  Draws from the parameter's Parameter::RandomPosterior function and then saves the result using Parameter::Save.
502
534
   */
503
535
  void DoStep() {
@@ -524,29 +556,35 @@ private:
524
556
  ParameterType parameter_;  
525
557
};
526
558
527
/*! Deterministic function step.
528
  * Deterministic nodes can be helpful to track summary statistics or to reduce computations through intermediate use
529
  * of sufficient statistics across multiple parameters.  FunctionStep calls the parameters Parameter::Function method
530
  * and saves the result using Parameter::Save.
531
  */
559
/*! \brief Deterministic function step.
560
 *
561
 * \ingroup steps
562
 * 
563
 * Deterministic nodes can be helpful to track summary statistics or to reduce computations through intermediate use
564
 * of sufficient statistics across multiple parameters.  FunctionStep calls the parameters Parameter::Function method
565
 * and saves the result using Parameter::Save.
566
 */
532
567
template <typename ParameterType>
533
568
class FunctionStep: public Step {
534
569
public:
535
570
  /// Default constructor, for copy assignments, etc.
536
571
  FunctionStep() {}
537
  /*! Main constructor taking a Parameter object.
572
  /*! \brief Main constructor taking a Parameter object.
573
   *
538
574
   *  \param parameter A Parameter that implements Parameter::Function.
539
575
   */
540
576
  FunctionStep(ParameterType parameter) : parameter_(parameter) {
541
577
  }
542
  /*! Take a function step for the parameter.
578
  /*! \brief Take a function step for the parameter.
579
   *
543
580
   *  Calculates the value of Parameter::Function and then saves the result using Parameter::Save.
544
581
   */
545
582
  void DoStep() {
546
583
    parameter_.Save(parameter_.Function());
547
584
  }
548
585
549
  /*! Set function step starting value.
586
  /*! \brief Set function step starting value.
587
   *
550
588
   * \note Because the starting value uses the normal function calculation, it is important to add
551
589
   * parameters in an order that makes the function feasible.  StartingValue functions are called in the order
552
590
   * they are added.  Any implemention of a StartingValue method for a FunctionStep will not be used.
@@ -571,26 +609,42 @@ private:
571
609
  ParameterType parameter_;  
572
610
};
573
611
574
575
/*! Normal proposal for MH.
612
/*! \defgroup proposals Metropolis-Hastings Proposals
613
 * 
614
 * The MetropStep Metropolis-Hastings class requires both a Parameter instance
615
 * and a Proposal instance.  Proposal instances define a Draw and LogDensity method.
616
 * The constructor should set a tuning parameter.
617
 *
618
 * MetroStep::DoStep uses the Draw method to draw new proposed values for the parameter
619
 * and the LogDensity to calculate the proposal terms in the acceptance \f$\alpha\f$.  For 
620
 * symmetric proposal distributions returning 0.0 is enough.
621
 */
622
 
623
/*! \brief Normal proposal for Metropolis-Hastings.
624
 *
625
 *  \ingroup proposals
626
 *
576
627
 *  Normal proposal draws from N(starting_value, standard_deviation).
577
628
 */
578
629
class NormalProposal {
579
630
public:
580
631
  NormalProposal() {}
581
  /*! Constructor
582
   * \param standard_deviation MH tuning parameter for normal model
632
  /*! \brief Constructor
633
   *
634
   * \param standard_deviation Tuning parameter for normal proposal.
583
635
   */
584
636
  NormalProposal(double standard_deviation) : standard_deviation_(standard_deviation) {}
585
637
  
586
  /*! Draw from normal proposal
638
  /*! \brief Draw from normal proposal
639
   *
587
640
   * \param starting_value Starting value.
588
641
   */
589
642
  double Draw(double starting_value) {
590
643
    return myrng.rnorm(starting_value, standard_deviation_);
591
644
  }
592
645
  
593
  /*! Log probability of proposal new value, given starting value.
646
  /*! \brief Log probability of proposal new value, given starting value.
647
   *
594
648
   * \note Needs to be implemented but can be 0.0 if proposal is symmetric, which it is.
595
649
   * \param starting_value Starting value.
596
650
   * \param new_value Proposed new value.
@@ -604,21 +658,132 @@ private:
604
658
};
605
659
606
660
607
/*! Metropolis Hastings step
608
  * Basic univariate Metropolis-Hastings step.  Requires both a Parameter and Proposal instance.
609
  */
661
/*! \brief Beta proposal for Metropolis-Hastings.
662
 *  
663
 * \ingroup proposals
664
 *
665
 * Useful proposal type for parameters with support between 0 and 1.
666
 *
667
 * The beta proposal is parameterized using the mean and the inverse denominator.  The denominator
668
 * is a measure a scale and can be thought of as the number of observed trials bernoulli.  We use the inverse
669
 * of the denominator so that larger values imply bigger steps, consistent with NormalProposal.  For the Beta distribution
670
 * the mean is
671
 * \f[ m = \frac{\alpha}{\alpha + \beta} \f]
672
 * and the denominator is
673
 * \f[ d = \alpha + \beta. \f]
674
 * Therefore
675
 * \f[ \alpha = m \cdot d \f]
676
 * and
677
 * \f[ \beta = d \cdot (1-m). \f]
678
 *
679
 */
680
class BetaProposal {
681
public:
682
  /*! \brief Empy constructor */
683
  BetaProposal() {}
684
  /*! \brief Main constructor
685
   *
686
   * Scale of steps are parameterized using the inverse denominator of a Beta distribution:
687
   * \f[ \frac{1}{d} = \frac{1}{\alpha + \beta} \f]
688
   *
689
   * \param idenominator Tuning parameter equal to the inverse denominator \f$1/d\f$ of a Beta distribution.
690
   */
691
  BetaProposal(double idenominator) : {
692
    denom_ = 1/idenominator;
693
  }
694
  
695
  /*! \brief Draw from Beta proposal
696
   *
697
   * \param starting_value Starting value (mean of Beta distribution).
698
   */
699
  double Draw(double starting_value) {
700
    double alpha_ = starting_value * denom_;
701
    double beta_ = alpha - denom_;
702
    return myrng.rbeta(alpha, beta);
703
  }
704
  
705
  /*! \brief Log probability of proposal new value, given starting value.
706
   * 
707
   * \param starting_value Starting value.
708
   * \param new_value Proposed new value.
709
   */
710
  double LogDensity(double new_value, double starting_value) {
711
    double alpha = starting_value * denom_;
712
    double beta = alpha - denom_;
713
    return myrng.dbeta(new_value, alpha, beta);
714
  }
715
  
716
private:
717
  double denom_;
718
};
719
720
721
/*! \brief Log normal proposal for Metropolis-Hastings.
722
 *  
723
 * \ingroup proposals
724
 *
725
 * Useful proposal type for parameters with support between 0 and positive infinity.
726
 *
727
 * For convenience, the log normal proposal is parameterized using the unlogged mean (starting value) 
728
 * and the (positive) log standard deviation.  This differs from how scythe::dlnorm is parameterized.
729
 *
730
 */
731
class LogNormalProposal {
732
public:
733
  /*! \brief Empy constructor */
734
  LogNormalProposal() {}
735
  /*! \brief Main constructor
736
   *
737
   * Scale of steps are standard deviation of the logged parameter value:
738
   *
739
   * \param logsd Tuning parameter equal to the log standard deviation.
740
   */
741
  LogNormalProposal(double logsd) : logsd_(logsd) {}
742
  
743
  /*! \brief Draw from log normal proposal
744
   *
745
   * \param starting_value Starting value (unlogged mean of log normal).
746
   */
747
  double Draw(double starting_value) {
748
    double logmean = log(starting_value);
749
    return myrng.rlnorm(logmean, logsd_);
750
  }
751
  
752
  /*! \brief Log probability of proposal new value, given starting value.
753
   * 
754
   * \param starting_value Starting value.
755
   * \param new_value Proposed new value.
756
   */
757
  double LogDensity(double new_value, double starting_value) {
758
    double logmean = log(starting_value);
759
    return myrng.dbeta(new_value, logmean, logsd_);
760
  }
761
  
762
private:
763
  double logsd_;
764
};
765
766
/*! \brief Metropolis Hastings step
767
 *
768
 * \ingroup steps
769
 * 
770
 * Basic univariate Metropolis-Hastings step.  Requires both a Parameter and Proposal instance.
771
 */
610
772
template <typename ParameterType, typename ProposalType>
611
773
class MetropStep: public Step {
612
774
public:
613
  /// Default constructor, for copy assignments, etc.
775
  /*! \brief Default constructor, for copy assignments, etc.
776
   */
614
777
  MetropStep() {}
615
  /*! Main constructor taking a Parameter and Proposal object.
778
  /*! \brief Main constructor taking a Parameter and Proposal object.
779
   *
616
780
   *  \param parameter A Parameter that implements Parameter::LogDensity
617
781
   *  \param proposal A Proposal instance that implements Proposal::LogDensity and Proposal::Draw.
618
782
   */
619
783
  MetropStep(ParameterType parameter, ProposalType proposal) : parameter_(parameter), proposal_(proposal) {}
620
784
  
621
  /*! Take a function step for the parameter.
785
  /*! \brief Take a function step for the parameter.
786
   *
622
787
   *  Calculates the value of Parameter::Function and then saves the result using Parameter::Save.
623
788
   */
624
789
  void DoStep() {
@@ -655,26 +820,30 @@ private:
655
820
};
656
821
657
822
/*! \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.
671
  */
823
 *
824
 * \ingroup steps
825
 *
826
 * Basic univariate slice sampling step with stepping out and shrinkage. Performs a slice sampling update from an initial
827
 * point to a new point that leaves invariant the distribution with the specifified log density functions.
828
 * 
829
 * The log desnity function may return -Inf for points outside the support of the distribution.
830
 * If a lower and/or upper bound is specified for the support, the log density function will not be called outside
831
 * such limits.
832
 *
833
 * \note See Neal, R. M (2003) "Slice Sampling" (with discussion), <i>Annals of Statistics</i>,
834
 * vol. 31, no. 3, pp. 705-767.
835
 * \note Code and description based on Neal's R code (March 17, 2008): http://www.cs.toronto.edu/~radford/ftp/slice-R-prog
836
 * \note With poor initial values or choice of w, slice sampling can get take a very long time to find
837
 * a suitable slice.  This may appear like a crash.  Experimenting with w may speed sampling, but things tends
838
 * to work pretty well with default values in many cases.
839
 */
672
840
template <typename ParameterType>
673
841
class SliceStep: public Step {
674
842
public:
675
843
  /// Default constructor, for copy assignments, etc.
676
844
  SliceStep() {}
677
  /*! Main constructor for slice sampling step.
845
  /*! \brief Main constructor for slice sampling step.
846
   *
678
847
   *  \param parameter A Parameter that implements Parameter::LogDensity
679
848
   *  \param w Size of the steps for creating interval (default = 1)
680
849
   *  \param lower Lower bound on the support of the distribution (default = -Infinity)
@@ -683,7 +852,8 @@ public:
683
852
  SliceStep(ParameterType parameter, double w = 1.0, double lower=-dInf, double upper=dInf) : 
684
853
    parameter_(parameter), w_(w), lower_(lower), upper_(upper) {}
685
854
  
686
  /*! Take a slice sampling step for the parameter.
855
  /*! \brief Take a slice sampling step for the parameter.
856
   *
687
857
   */
688
858
  void DoStep() {
689
859
    // Find the log density at the initial point.
@@ -777,6 +947,7 @@ private:
777
947
};
778
948
779
949
/*! \brief MCMC sampler.
950
 *
780
951
 *  The sampler is the main MCMC object that holds all the MCMC steps for each parameter.  Running the sampler
781
952
 *  performs MCMC sampling for the model, saving results, and displaying progress.  In the language of the Command Pattern, the
782
953
 *  sampler is the Invoker or Command Manager.
@@ -786,7 +957,8 @@ private:
786
957
 */
787
958
class Sampler {
788
959
public:
789
  /*! \beif  Constructor to initialize sampler.
960
  /*! \brief  Constructor to initialize sampler.
961
   *
790
962
   *  \param options MCMC options object that defines sample_size, burnin, thinning interval, etc.
791
963
   */
792
964
  Sampler(MCMCOptions options) {
@@ -797,6 +969,7 @@ public:
797
969
    out_file_ = options.out_file;
798
970
  }
799
971
  /*! \brief Add Step to Sampler execution stack.
972
   *
800
973
   *  All parameters should have an associated Step that is added to the sampler.  The sampler stack
801
974
   *  defines one sampler iteration.
802
975
   *  \param step Step object for a given parameter.
@@ -809,7 +982,8 @@ public:
809
982
      tracks_.push_back(steps_.size() - 1);
810
983
    }
811
984
  }
812
  /*! Run sampler for a specific number of iterations.
985
  /*! \brief Run sampler for a specific number of iterations.
986
   *
813
987
   * \param number_of_iterations Number of iterations to run sampler.
814
988
   * \param progress Display a progress bar.
815
989
   */
@@ -831,7 +1005,8 @@ public:
831
1005
      }
832
1006
    }
833
1007
  }
834
  /*! Run sampler.
1008
  /*! \brief Run sampler.
1009
   *
835
1010
   * Run the MCMC sampling procedure, including burning in, sampling, thinning, displaying progress,
836
1011
   * and saving results.
837
1012
   */
@@ -892,13 +1067,15 @@ public:
892
1067
    
893
1068
    cout << "Total elapsed time: " << timer.elapsed() << " seconds" << endl;
894
1069
  }
895
  /*! Number of steps in one sampler iteration.
1070
  /*! \brief Number of steps in one sampler iteration.
1071
   *
896
1072
   * \return Number of steps.
897
1073
   */
898
1074
  int NumberOfSteps() {
899
1075
    return steps_.size();
900
1076
  }
901
  /*! Number of tracked steps in one sampler iteration.
1077
  /*! \brief Number of tracked steps in one sampler iteration.
1078
   *
902
1079
   * \return Number of tracked steps.
903
1080
   */
904
1081
  int NumberOfTrackedSteps() {
@@ -913,7 +1090,8 @@ private:
913
1090
  vector<int> tracks_;
914
1091
};
915
1092
916
/*! Approximately equal.
1093
/*! \brief Approximately equal.
1094
 *
917
1095
 *  Checks if two doubles are within the numeric_limits<double>::epsilon() precision of each other.
918
1096
 *  Useful if === is too strict.
919
1097
 */