00001
00002
00003
00004
00005 #ifndef PRIOR_H
00006 #define PRIOR_H
00007
00008 #include <cmath>
00009 #include "rng.h"
00010 #include "special.h"
00011
00018 class PsiPrior
00019 {
00020 private:
00021 PsiRandom rng;
00022 public:
00023 virtual double pdf ( double x ) const { return 1.;}
00024 virtual double dpdf ( double x ) { return 0.; }
00025 virtual double rand ( void ) { return rng.draw(); }
00026 virtual PsiPrior * clone ( void ) const { throw NotImplementedError(); }
00027 virtual double mean ( void ) const { return 0; }
00028 virtual double std ( void ) const { return 1e5; }
00029 virtual void shrink ( double xmin, double xmax ) { throw NotImplementedError(); }
00030 virtual int get_code(void) const { throw NotImplementedError(); }
00031 virtual double cdf ( double x ) const { throw NotImplementedError(); }
00032 virtual double getprm ( unsigned int prm ) const { throw NotImplementedError(); }
00033 virtual double ppf ( double p, double start=NULL ) const { throw NotImplementedError(); }
00034 };
00035
00041 class UniformPrior : public PsiPrior
00042 {
00043 private:
00044 double lower;
00045 double upper;
00046 double height;
00047 UniformRandom rng;
00048 public:
00049 UniformPrior ( double low, double high ) : lower(low), upper(high), rng ( low, high ) { height = 1./(high-low); }
00050 UniformPrior ( const UniformPrior& original ) : lower(original.lower),
00051 upper(original.upper),
00052 height(original.height),
00053 rng(original.rng) {}
00054 double pdf ( double x ) const { return ( x>lower && x<upper ? height : 0 ); }
00055 double dpdf ( double x ) { return ( x!=lower && x!=upper ? 0 : (x==lower ? 1e20 : -1e20 ));}
00056 double rand ( void ) { return rng.draw(); }
00057 PsiPrior * clone ( void ) const { return new UniformPrior(*this); }
00058 double mean ( void ) const { return 0.5*(lower+upper); }
00059 double std ( void ) const { return sqrt((upper-lower)*(upper-lower)/12); }
00060 void shrink ( double xmin, double xmax ) {}
00061 int get_code(void) const { return 0; }
00062 double cdf ( double x ) const { return ( x<lower ? 0 : (x>upper ? 1 : (x-lower)/(upper-lower) ) ); }
00063 double getprm ( unsigned int prm ) const { return (prm==0 ? lower : upper ); }
00064 double ppf ( double p, double start=NULL ) const { return ( p>1 ? upper : (p<0 ? lower : p*(upper-lower)+lower)); }
00065 };
00066
00075 class GaussPrior : public PsiPrior
00076 {
00077 private:
00078 double mu;
00079 double sg;
00080 double normalization;
00081 double var;
00082 double twovar;
00083 GaussRandom rng;
00084 public:
00085 GaussPrior ( double mean, double sd ) : mu(mean), sg(sd), var(sg*sg), twovar(2*sg*sg), rng(mean,sd) { normalization = 1./(sqrt(2*M_PI)*sg); }
00086 GaussPrior ( const GaussPrior& original ) : mu(original.mu),
00087 sg(original.sg),
00088 normalization(original.normalization),
00089 var(original.var),
00090 twovar(original.twovar),
00091 rng(original.rng) {}
00092 double pdf ( double x ) const { return normalization * exp ( - (x-mu)*(x-mu)/twovar ); }
00093 double dpdf ( double x ) { return - x * pdf ( x ) / var; }
00094 double rand ( void ) {return rng.draw(); }
00095 PsiPrior * clone ( void ) const { return new GaussPrior(*this); }
00096 double mean ( void ) const { return mu; }
00097 double std ( void ) const { return sg; }
00098 void shrink ( double xmin, double xmax );
00099 int get_code(void) const { return 1; }
00100 double cdf ( double x ) const { return Phi ( (x-mu)/sg ); }
00101 double getprm ( unsigned int prm ) const { return ( prm==0 ? mu : sg ); }
00102 double ppf ( double p, double start=NULL ) const;
00103 };
00104
00115 class BetaPrior : public PsiPrior
00116 {
00117 private:
00118 double alpha;
00119 double beta;
00120 double normalization;
00121 BetaRandom rng;
00122 double mode;
00123 public:
00124 BetaPrior ( double al, double bt ) : alpha(al), beta(bt), normalization(betaf(al,bt)), rng (alpha, beta) {
00125 mode = (al-1)/(al+bt-2);
00126 mode = pdf(mode); }
00127 BetaPrior ( const BetaPrior& original) : alpha(original.alpha),
00128 beta(original.beta),
00129 normalization(original.normalization),
00130 rng(original.rng),
00131 mode(original.mode) {}
00132 double pdf ( double x ) const { return (x<0||x>1 ? 0 : pow(x,alpha-1)*pow(1-x,beta-1)/normalization); }
00133 double dpdf ( double x ) { return (x<0||x>1 ? 0 : ((alpha-1)*pow(x,alpha-2)*pow(1-x,beta-1) + (beta-1)*pow(1-x,beta-2)*pow(x,alpha-1))/normalization); }
00134 double rand ( void ) {return rng.draw();};
00135 PsiPrior * clone ( void ) const { return new BetaPrior(*this); }
00136 double mean ( void ) const { return alpha/(alpha+beta); }
00137 double std ( void ) const { return sqrt ( alpha*beta/((alpha+beta)*(alpha+beta)*(alpha+beta+1)) ); }
00138 void shrink ( double xmin, double xmax );
00139 int get_code(void) const { return 2; }
00140 double cdf ( double x ) const { return (x<0 ? 0 : (x>1 ? 1 : betainc ( x, alpha, beta ))); }
00141 double getprm ( unsigned int prm ) const { return ( prm==0 ? alpha : beta ); }
00142 double ppf ( double p, double start=NULL ) const;
00143 };
00144
00154 class GammaPrior : public PsiPrior
00155 {
00156 private:
00157 double k;
00158 double theta;
00159 double normalization;
00160 GammaRandom rng;
00161 public:
00162 GammaPrior ( double shape, double scale ) : k(shape), theta(scale), rng(shape, scale) { normalization = pow(scale,shape)*exp(gammaln(shape));}
00163 GammaPrior ( const GammaPrior& original ) : k(original.k),
00164 theta(original.theta),
00165 normalization(original.normalization),
00166 rng(original.rng) {}
00167 virtual double pdf ( double x ) const { return (x>0 ? pow(x,k-1)*exp(-x/theta)/normalization : 0 );}
00168 virtual double dpdf ( double x ) { return (x>0 ? ( (k-1)*pow(x,k-2)*exp(-x/theta)-pow(x,k-1)*exp(-x/theta)/theta)/normalization : 0 ); }
00169 virtual double rand ( void ) {return rng.draw(); };
00170 PsiPrior * clone ( void ) const { return new GammaPrior(*this); }
00171 virtual double mean ( void ) const { return k*theta; }
00172 double std ( void ) const { return sqrt ( k*theta*theta ); }
00173 void shrink ( double xmin, double xmax );
00174 virtual int get_code(void) const { return 3; }
00175 virtual double cdf ( double x ) const { return ( x<0 ? 0 : gammainc ( k, x/theta ) / exp ( gammaln ( k ) ) ); }
00176 double getprm ( unsigned int prm ) const { return ( prm==0 ? k : theta ); }
00177 virtual double ppf ( double p, double start=NULL ) const;
00178 };
00179
00189 class nGammaPrior : public GammaPrior
00190 {
00191 public:
00192 nGammaPrior ( double shape, double scale ) : GammaPrior(shape,scale) {}
00193 nGammaPrior ( const nGammaPrior& original ) : GammaPrior(original) {}
00194 double pdf ( double x ) const { return GammaPrior::pdf ( -x ); }
00195 double dpdf ( double x ) { return -GammaPrior::dpdf ( -x ); }
00196 double rand ( void ) { return -GammaPrior::rand(); }
00197 PsiPrior * clone ( void ) const { return new nGammaPrior(*this); }
00198 double mean ( void ) const { return -GammaPrior::mean(); }
00199 void shrink ( double xmin, double xmax );
00200 int get_code(void) const { return 4; }
00201 double cdf ( double x ) const { return ( x>0 ? 1 : 1-GammaPrior::cdf ( -x ) ); }
00202 double ppf ( double p, double start=NULL ) const { return - GammaPrior::ppf ( 1-p ); }
00203 };
00204
00215 class invGammaPrior : public PsiPrior
00216 {
00217 private:
00218 double alpha;
00219 double beta;
00220 double normalization;
00221 GammaRandom rng;
00222 public:
00223 invGammaPrior ( double shape, double scale ) : alpha ( shape ), beta ( scale ), rng ( shape, 1./scale ) { normalization = pow(alpha,beta)/exp(gammaln(shape));}
00224 invGammaPrior ( const invGammaPrior& original ) : alpha(original.alpha),
00225 beta(original.beta),
00226 normalization ( original.normalization ),
00227 rng(original.rng) {}
00228 virtual double pdf ( double x ) { return ( x>0 ? pow ( x, -alpha-1 ) * exp ( -beta/x ) * normalization : 0 ); }
00229 virtual double dpdf ( double x ) { return (x>0 ? ( (-alpha-1)*pow(x,-alpha-2) * exp ( -beta/x ) + pow(x,-alpha-1) * exp ( -beta/x ) * beta / (x*x) ) * normalization : 0 ); }
00230 virtual double rand ( void ) { return 1./rng.draw(); }
00231 PsiPrior * clone ( void ) const { return new invGammaPrior(*this); }
00232 virtual double mean ( void ) const { return beta/(alpha-1); }
00233 double std ( void ) const { return ( alpha>2 ? beta / ( (alpha-1)*sqrt(alpha-2) ) : 1e5 ); }
00234 virtual void shrink ( double xmin, double xmax ) {}
00235 virtual int get_code ( void ) const { return 5; }
00236 };
00237
00248 class ninvGammaPrior : public invGammaPrior
00249 {
00250 public:
00251 ninvGammaPrior ( double shape, double scale ) : invGammaPrior ( shape, scale ) {}
00252 ninvGammaPrior ( const ninvGammaPrior& original ) : invGammaPrior ( original ) {}
00253 double pdf ( double x ) { return invGammaPrior::pdf ( -x ); }
00254 double dpdf ( double x ) { return -invGammaPrior::dpdf ( -x ); }
00255 double rand ( void ) { return -invGammaPrior::rand(); }
00256 PsiPrior * clone ( void ) const { return new ninvGammaPrior ( *this ); }
00257 double mean ( void ) const { return -invGammaPrior::mean(); }
00258 void shrink ( double xmin, double xmax ) { invGammaPrior::shrink ( -xmax, -xmin ); }
00259 int get_code ( void ) const { return 6; }
00260 };
00261 #endif