00001
00002
00003
00004
00005 #ifndef MCMC_H
00006 #define MCMC_H
00007
00008 #include <vector>
00009 #include "psychometric.h"
00010 #include "rng.h"
00011 #include "mclist.h"
00012 #include "getstart.h"
00013
00014 class PsiSampler
00015 {
00016 private:
00017 const PsiPsychometric * model;
00018 const PsiData * data;
00019 public:
00020 PsiSampler ( const PsiPsychometric * Model, const PsiData * Data ) : model(Model), data(Data) {}
00021 virtual std::vector<double> draw ( void ) { throw NotImplementedError(); }
00022 virtual void setTheta ( const std::vector<double> theta ) { throw NotImplementedError(); }
00023 virtual std::vector<double> getTheta ( void ) { throw NotImplementedError(); }
00024 virtual void setStepSize ( double size, unsigned int param ) { throw NotImplementedError(); }
00025 virtual void setStepSize ( const std::vector<double>& sizes ) { throw NotImplementedError(); }
00026 virtual double getDeviance ( void ) { throw NotImplementedError(); }
00027 virtual MCMCList sample ( unsigned int N ) { throw NotImplementedError(); }
00028 const PsiPsychometric * getModel() const { return model; }
00029 const PsiData * getData() const { return data; }
00030 };
00031
00032 class MetropolisHastings : public PsiSampler
00033 {
00034 private:
00035 PsiRandom* propose;
00036 std::vector<double> currenttheta;
00037 std::vector<double> newtheta;
00038 std::vector<double> stepwidths;
00039 double currentdeviance;
00040 int accept;
00041 protected:
00042 double qold;
00043 public:
00044 MetropolisHastings (
00045 const PsiPsychometric * Model,
00046 const PsiData * Data,
00047 PsiRandom* proposal
00048 );
00049 ~MetropolisHastings ( void ) { delete propose; }
00050 std::vector<double> draw ( void );
00051 virtual double acceptance_probability ( const std::vector<double>& current_theta, const std::vector<double>& new_theta );
00052 void setTheta ( const std::vector<double>& prm );
00053 std::vector<double> getTheta ( void ) { return currenttheta; }
00054 double getDeviance ( void ) { return currentdeviance; }
00055 void setStepSize ( double size, unsigned int param );
00056 void setStepSize ( const std::vector<double>& sizes );
00057 std::vector<double> getStepsize ( void ) { return stepwidths; }
00058 MCMCList sample ( unsigned int N );
00059 unsigned int getNparams ( void ) { return newtheta.size(); }
00060 virtual void proposePoint( std::vector<double> ¤t_theta,
00061 std::vector<double> &step_widths,
00062 PsiRandom * proposal,
00063 std::vector<double> &new_theta);
00064 };
00065
00066 class GenericMetropolis : public MetropolisHastings
00067 {
00068 private:
00069 int currentindex;
00070 public:
00071 GenericMetropolis (
00072 const PsiPsychometric * Model,
00073 const PsiData * Data,
00074 PsiRandom* proposal
00075 ): MetropolisHastings ( Model, Data, proposal ),
00076 currentindex(0) {}
00077 void proposePoint( std::vector<double> ¤t_theta,
00078 std::vector<double> &step_widths,
00079 PsiRandom * proposal,
00080 std::vector<double> &new_theta);
00081
00088 void findOptimalStepwidth ( PsiMClist const &pilot );
00089 };
00090
00091 class DefaultMCMC : public MetropolisHastings
00092 {
00093 private:
00094 std::vector<PsiPrior*> proposaldistributions;
00095 public:
00096 DefaultMCMC ( const PsiPsychometric * Model,
00097 const PsiData * Data,
00098 PsiRandom* proposal
00099 );
00100 ~DefaultMCMC ( void );
00101 double acceptance_probability (
00102 const std::vector<double> ¤t_theta,
00103 const std::vector<double> &new_theta );
00104 void proposePoint ( std::vector<double> ¤t_theta,
00105 std::vector<double> &stepwidths,
00106 PsiRandom * proposal,
00107 std::vector<double> &new_theta);
00108 void set_proposal(unsigned int i, PsiPrior* proposal){
00109 delete proposaldistributions.at(i);
00110 proposaldistributions.at(i) = proposal->clone();
00111 }
00112 };
00113
00114 class HybridMCMC : public PsiSampler
00115 {
00116 private:
00117 PsiRandom* proposal;
00118 std::vector<double> currenttheta;
00119 std::vector<double> newtheta;
00120 std::vector<double> momentum;
00121 double currentH;
00122 double newH;
00123 double energy;
00124 double newenergy;
00125 std::vector<double> gradient;
00126 std::vector<double> currentgradient;
00127 std::vector<double> stepsizes;
00128 int Nleapfrog;
00129 int Naccepted;
00130 void leapfrog ( void );
00131 public:
00132 HybridMCMC (
00133 const PsiPsychometric * Model,
00134 const PsiData * Data,
00135 int Nleap
00136 );
00137 ~HybridMCMC ( void ) { delete proposal; }
00138 std::vector<double> draw ( void );
00139 void setTheta ( const std::vector<double>& prm );
00140 std::vector<double> getTheta ( void ) { return currenttheta; }
00141 void setStepSize ( double size, unsigned int param );
00142 void setStepSize ( const std::vector<double>& sizes );
00143 double getDeviance ( void );
00144 MCMCList sample ( unsigned int N );
00145 };
00146
00168 double ModelEvidence ( const PsiPsychometric* pmf, const PsiData* data );
00169
00192 std::vector<double> OutlierDetection ( const PsiPsychometric* pmf, OutlierModel* outl, const PsiData* data );
00193
00194 #endif