MUQ  0.4.3
Gamma.cpp
Go to the documentation of this file.
3 #include <Eigen/Core>
4 
5 using namespace muq::Modeling;
6 using namespace muq::Utilities;
7 
8 Gamma::Gamma(Eigen::VectorXd const& alphaIn,
9  Eigen::VectorXd const& betaIn) : Distribution(alphaIn.size()),
10  alpha(alphaIn),
11  beta(betaIn),
12  logConst(ComputeConstant(alphaIn, betaIn))
13  {};
14 
15 Gamma::Gamma(double alphaIn,
16  double betaIn) : Gamma(alphaIn*Eigen::VectorXd::Ones(1),
17  betaIn*Eigen::VectorXd::Ones(1)){};
18 
19 double Gamma::ComputeConstant(Eigen::VectorXd const& alphaIn,
20  Eigen::VectorXd const& betaIn)
21 {
22  double logConst = 0;
23  for(int i=0; i<alphaIn.size(); ++i)
24  logConst += alphaIn(i)*std::log(betaIn(i)) - std::lgamma(alphaIn(i));
25 
26  return logConst;
27 }
28 
30 {
31  Eigen::VectorXd const& x = inputs.at(0).get();
32 
33  if(x.minCoeff()<std::numeric_limits<double>::epsilon())
34  return -1.0*std::numeric_limits<double>::infinity();
35 
36  return logConst + ((alpha.array()-1.0)*x.array().log() - beta.array()*x.array()).sum();
37 }
38 
39 
40 Eigen::VectorXd Gamma::SampleImpl(ref_vector<Eigen::VectorXd> const& inputs)
41 {
42  Eigen::VectorXd output(alpha.size());
43  for(int i=0; i<alpha.size(); ++i)
44  output(i) = RandomGenerator::GetGamma(alpha(i),1.0/beta(i));
45 
46  return output;
47 }
48 
49 Eigen::VectorXd Gamma::GradLogDensity(unsigned int wrt,
50  ref_vector<Eigen::VectorXd> const& inputs)
51 {
52  Eigen::VectorXd const& x = inputs.at(0).get();
53 
54  Eigen::VectorXd grad(x.size());
55  for(int i=0; i<x.size(); ++i){
56  if(x(i)<std::numeric_limits<double>::epsilon()){
57  grad(i) = 0.0;
58  }else{
59  grad(i) = (alpha(i)-1.0)/x(i) - beta(i);
60  }
61  }
62 
63  return grad;
64 }
65 
66 Eigen::VectorXd Gamma::ApplyLogDensityHessian(unsigned int const inWrt1,
67  unsigned int const inWrt2,
68  ref_vector<Eigen::VectorXd> const& inputs,
69  Eigen::VectorXd const& vec)
70 {
71  Eigen::VectorXd const& x = inputs.at(0).get();
72 
73  Eigen::VectorXd hessAct(x.size());
74 
75  for(int i=0; i<x.size(); ++i){
76  if(x(i)<std::numeric_limits<double>::epsilon()){
77  hessAct(i) = 0.0;
78  }else{
79  hessAct(i) = -1.0 * vec(i) * (alpha(i)-1.0)/(x(i)*x(i));
80  }
81  }
82 
83  return hessAct;
84 }
85 
86 
87 std::shared_ptr<Gamma> Gamma::FromMoments(Eigen::VectorXd const& mean,
88  Eigen::VectorXd const& var)
89 {
90  Eigen::VectorXd beta = mean.array() / var.array();
91  Eigen::VectorXd alpha = mean.array()*beta.array();
92  return std::make_shared<Gamma>(alpha,beta);
93 }
const Eigen::VectorXd beta
Definition: Gamma.h:36
virtual Eigen::VectorXd SampleImpl(ref_vector< Eigen::VectorXd > const &inputs) override
Sample the distribution.
Definition: Gamma.cpp:40
virtual double LogDensityImpl(ref_vector< Eigen::VectorXd > const &inputs) override
Implement the log-density.
Definition: Gamma.cpp:29
virtual Eigen::VectorXd ApplyLogDensityHessian(unsigned int const inWrt1, unsigned int const inWrt2, ref_vector< Eigen::VectorXd > const &input, Eigen::VectorXd const &vec) override
Definition: Gamma.cpp:66
const Eigen::VectorXd alpha
Definition: Gamma.h:35
static double ComputeConstant(Eigen::VectorXd const &alphaIn, Eigen::VectorXd const &betaIn)
Definition: Gamma.cpp:19
const double logConst
Definition: Gamma.h:43
virtual Eigen::VectorXd GradLogDensity(unsigned int wrt, ref_vector< Eigen::VectorXd > const &inputs) override
Definition: Gamma.cpp:49
static std::shared_ptr< Gamma > FromMoments(Eigen::VectorXd const &mean, Eigen::VectorXd const &var)
Definition: Gamma.cpp:87
Gamma(double alphaIn, double betaIn)
Definition: Gamma.cpp:15
std::vector< std::reference_wrapper< const T > > ref_vector
A vector of references to something ...
Definition: WorkPiece.h:37