SHOGUN  4.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
GaussianLikelihood.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2013 Roman Votyakov
8  * Copyright (C) 2012 Jacob Walker
9  * Copyright (C) 2013 Roman Votyakov
10  */
11 
13 
14 #ifdef HAVE_EIGEN3
15 
18 
19 using namespace shogun;
20 using namespace Eigen;
21 
23 {
24  init();
25 }
26 
28 {
29  init();
30  set_sigma(sigma);
31 }
32 
33 void CGaussianLikelihood::init()
34 {
35  m_log_sigma=0.0;
36  SG_ADD(&m_log_sigma, "log_sigma", "Observation noise in log domain", MS_AVAILABLE, GRADIENT_AVAILABLE);
37 }
38 
40 {
41 }
42 
44  CLikelihoodModel* lik)
45 {
46  ASSERT(lik!=NULL);
47 
48  if (lik->get_model_type()!=LT_GAUSSIAN)
49  SG_SERROR("Provided likelihood is not of type CGaussianLikelihood!\n")
50 
51  SG_REF(lik);
52  return (CGaussianLikelihood*)lik;
53 }
54 
56  SGVector<float64_t> mu, SGVector<float64_t> s2, const CLabels* lab) const
57 {
58  return SGVector<float64_t>(mu);
59 }
60 
62  SGVector<float64_t> mu, SGVector<float64_t> s2, const CLabels* lab) const
63 {
64  SGVector<float64_t> result(s2);
65  Map<VectorXd> eigen_result(result.vector, result.vlen);
66 
67  eigen_result=eigen_result.array()+CMath::exp(m_log_sigma*2.0);
68 
69  return result;
70 }
71 
73  SGVector<float64_t> func) const
74 {
75  // check the parameters
76  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
78  "Labels must be type of CRegressionLabels\n")
79  REQUIRE(lab->get_num_labels()==func.vlen, "Number of labels must match "
80  "length of the function vector\n")
81 
82  Map<VectorXd> eigen_f(func.vector, func.vlen);
83 
84  SGVector<float64_t> result(func.vlen);
85  Map<VectorXd> eigen_result(result.vector, result.vlen);
86 
87  SGVector<float64_t> y=((CRegressionLabels*)lab)->get_labels();
88  Map<VectorXd> eigen_y(y.vector, y.vlen);
89 
90  // compute log probability: lp=-(y-f).^2./sigma^2/2-log(2*pi*sigma^2)/2
91  eigen_result=eigen_y-eigen_f;
92  eigen_result=-eigen_result.cwiseProduct(eigen_result)/(2.0*CMath::exp(m_log_sigma*2.0))-
93  VectorXd::Ones(result.vlen)*log(2.0*CMath::PI*CMath::exp(m_log_sigma*2.0))/2.0;
94 
95  return result;
96 }
97 
99  const CLabels* lab, SGVector<float64_t> func, index_t i) const
100 {
101  // check the parameters
102  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
104  "Labels must be type of CRegressionLabels\n")
105  REQUIRE(lab->get_num_labels()==func.vlen, "Number of labels must match "
106  "length of the function vector\n")
107  REQUIRE(i>=1 && i<=3, "Index for derivative should be 1, 2 or 3\n")
108 
109  Map<VectorXd> eigen_f(func.vector, func.vlen);
110 
111  SGVector<float64_t> result(func.vlen);
112  Map<VectorXd> eigen_result(result.vector, result.vlen);
113 
114  SGVector<float64_t> y=((CRegressionLabels*)lab)->get_labels();
115  Map<VectorXd> eigen_y(y.vector, y.vlen);
116 
117  // set result=y-f
118  eigen_result=eigen_y-eigen_f;
119 
120  // compute derivatives of log probability wrt f
121  if (i == 1)
122  eigen_result/=CMath::exp(m_log_sigma*2.0);
123  else if (i == 2)
124  eigen_result=-VectorXd::Ones(result.vlen)/CMath::exp(m_log_sigma*2.0);
125  else if (i == 3)
126  eigen_result=VectorXd::Zero(result.vlen);
127 
128  return result;
129 }
130 
132  SGVector<float64_t> func, const TParameter* param) const
133 {
134  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
136  "Labels must be type of CRegressionLabels\n")
137  REQUIRE(lab->get_num_labels()==func.vlen, "Number of labels must match "
138  "length of the function vector\n")
139 
140  Map<VectorXd> eigen_f(func.vector, func.vlen);
141 
142  SGVector<float64_t> result(func.vlen);
143  Map<VectorXd> eigen_result(result.vector, result.vlen);
144 
145  if (strcmp(param->m_name, "log_sigma"))
146  return SGVector<float64_t>();
147 
148  SGVector<float64_t> y=((CRegressionLabels*)lab)->get_labels();
149  Map<VectorXd> eigen_y(y.vector, y.vlen);
150 
151  // compute derivative of log probability wrt log_sigma:
152  // dlp_dlogsigma
153  // lp_dsigma=(y-f).^2/sigma^2-1
154  eigen_result=eigen_y-eigen_f;
155  eigen_result=eigen_result.cwiseProduct(eigen_result)/CMath::exp(m_log_sigma*2.0);
156  eigen_result-=VectorXd::Ones(result.vlen);
157 
158  return result;
159 }
160 
162  SGVector<float64_t> func, const TParameter* param) const
163 {
164  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
166  "Labels must be type of CRegressionLabels\n")
167  REQUIRE(lab->get_num_labels()==func.vlen, "Number of labels must match "
168  "length of the function vector\n")
169 
170  if (strcmp(param->m_name, "log_sigma"))
171  return SGVector<float64_t>();
172 
173  Map<VectorXd> eigen_f(func.vector, func.vlen);
174 
175  SGVector<float64_t> result(func.vlen);
176  Map<VectorXd> eigen_result(result.vector, result.vlen);
177 
178  SGVector<float64_t> y=((CRegressionLabels*)lab)->get_labels();
179  Map<VectorXd> eigen_y(y.vector, y.vlen);
180 
181  // compute derivative of (the first log_sigma derivative of log probability) wrt f:
182  // d2lp_dlogsigma_df == d2lp_df_dlogsigma
183  // dlp_dsigma=2*(f-y)/sigma^2
184  eigen_result=2.0*(eigen_f-eigen_y)/CMath::exp(m_log_sigma*2.0);
185 
186  return result;
187 }
188 
190  SGVector<float64_t> func, const TParameter* param) const
191 {
192  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
194  "Labels must be type of CRegressionLabels\n")
195  REQUIRE(lab->get_num_labels()==func.vlen, "Number of labels must match "
196  "length of the function vector\n")
197 
198  if (strcmp(param->m_name, "log_sigma"))
199  return SGVector<float64_t>();
200 
201  Map<VectorXd> eigen_f(func.vector, func.vlen);
202 
203  SGVector<float64_t> result(func.vlen);
204  Map<VectorXd> eigen_result(result.vector, result.vlen);
205 
206  // compute derivative of (the derivative of the first log_sigma derivative of log probability) wrt f:
207  // d3lp_dlogsigma_df_df == d3lp_df_df_dlogsigma
208  // d2lp_dsigma=2/sigma^2
209  eigen_result=2.0*VectorXd::Ones(result.vlen)/CMath::exp(m_log_sigma*2.0);
210 
211  return result;
212 }
213 
215  SGVector<float64_t> mu, SGVector<float64_t> s2, const CLabels *lab) const
216 {
218 
219  if (lab)
220  {
221  REQUIRE((mu.vlen==s2.vlen) && (mu.vlen==lab->get_num_labels()),
222  "Length of the vector of means (%d), length of the vector of "
223  "variances (%d) and number of labels (%d) should be the same\n",
224  mu.vlen, s2.vlen, lab->get_num_labels())
226  "Labels must be type of CRegressionLabels\n")
227 
228  y=((CRegressionLabels*)lab)->get_labels();
229  }
230  else
231  {
232  REQUIRE(mu.vlen==s2.vlen, "Length of the vector of means (%d) and "
233  "length of the vector of variances (%d) should be the same\n",
234  mu.vlen, s2.vlen)
235 
237  y.set_const(1.0);
238  }
239 
240  // create eigen representation of y, mu and s2
241  Map<VectorXd> eigen_mu(mu.vector, mu.vlen);
242  Map<VectorXd> eigen_s2(s2.vector, s2.vlen);
243  Map<VectorXd> eigen_y(y.vector, y.vlen);
244 
245  SGVector<float64_t> result(mu.vlen);
246  Map<VectorXd> eigen_result(result.vector, result.vlen);
247 
248  // compule lZ=-(y-mu).^2./(sn2+s2)/2-log(2*pi*(sn2+s2))/2
249  eigen_s2=eigen_s2.array()+CMath::exp(m_log_sigma*2.0);
250  eigen_result=-(eigen_y-eigen_mu).array().square()/(2.0*eigen_s2.array())-
251  (2.0*CMath::PI*eigen_s2.array()).log()/2.0;
252 
253  return result;
254 }
255 
257  SGVector<float64_t> s2, const CLabels *lab, index_t i) const
258 {
259  // check the parameters
260  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
261  REQUIRE((mu.vlen==s2.vlen) && (mu.vlen==lab->get_num_labels()),
262  "Length of the vector of means (%d), length of the vector of "
263  "variances (%d) and number of labels (%d) should be the same\n",
264  mu.vlen, s2.vlen, lab->get_num_labels())
265  REQUIRE(i>=0 && i<=mu.vlen, "Index (%d) out of bounds!\n", i)
267  "Labels must be type of CRegressionLabels\n")
268 
269  SGVector<float64_t> y=((CRegressionLabels*)lab)->get_labels();
270 
271  // compute 1st moment
272  float64_t Ex=mu[i]+s2[i]*(y[i]-mu[i])/(CMath::exp(m_log_sigma*2.0)+s2[i]);
273 
274  return Ex;
275 }
276 
278  SGVector<float64_t> s2, const CLabels *lab, index_t i) const
279 {
280  // check the parameters
281  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
282  REQUIRE((mu.vlen==s2.vlen) && (mu.vlen==lab->get_num_labels()),
283  "Length of the vector of means (%d), length of the vector of "
284  "variances (%d) and number of labels (%d) should be the same\n",
285  mu.vlen, s2.vlen, lab->get_num_labels())
286  REQUIRE(i>=0 && i<=mu.vlen, "Index (%d) out of bounds!\n", i)
288  "Labels must be type of CRegressionLabels\n")
289 
290  // compute 2nd moment
291  float64_t Var=s2[i]-CMath::sq(s2[i])/(CMath::exp(m_log_sigma*2.0)+s2[i]);
292 
293  return Var;
294 }
295 
296 #endif /* HAVE_EIGEN3 */
virtual ELabelType get_label_type() const =0
Class that models Gaussian likelihood.
Real Labels are real-valued labels.
virtual SGVector< float64_t > get_log_probability_f(const CLabels *lab, SGVector< float64_t > func) const
int32_t index_t
Definition: common.h:62
The class Labels models labels, i.e. class assignments of objects.
Definition: Labels.h:43
virtual int32_t get_num_labels() const =0
real valued labels (e.g. for regression, classifier outputs)
Definition: LabelTypes.h:22
static T sq(T x)
Definition: Math.h:450
Definition: SGMatrix.h:20
virtual ELikelihoodModelType get_model_type() const
parameter struct
#define REQUIRE(x,...)
Definition: SGIO.h:206
void set_sigma(float64_t sigma)
#define SG_REF(x)
Definition: SGObject.h:51
virtual float64_t get_second_moment(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab, index_t i) const
virtual SGVector< float64_t > get_first_derivative(const CLabels *lab, SGVector< float64_t > func, const TParameter *param) const
index_t vlen
Definition: SGVector.h:494
virtual SGVector< float64_t > get_predictive_variances(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab=NULL) const
#define ASSERT(x)
Definition: SGIO.h:201
virtual SGVector< float64_t > get_predictive_means(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab=NULL) const
double float64_t
Definition: common.h:50
virtual float64_t get_first_moment(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab, index_t i) const
static CGaussianLikelihood * obtain_from_generic(CLikelihoodModel *lik)
virtual SGVector< float64_t > get_second_derivative(const CLabels *lab, SGVector< float64_t > func, const TParameter *param) const
virtual SGVector< float64_t > get_log_zeroth_moments(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab) const
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
#define SG_SERROR(...)
Definition: SGIO.h:179
static float64_t exp(float64_t x)
Definition: Math.h:621
virtual SGVector< float64_t > get_log_probability_derivative_f(const CLabels *lab, SGVector< float64_t > func, index_t i) const
#define SG_ADD(...)
Definition: SGObject.h:81
virtual SGVector< float64_t > get_third_derivative(const CLabels *lab, SGVector< float64_t > func, const TParameter *param) const
The Likelihood model base class.
void set_const(T const_elem)
Definition: SGVector.cpp:152
static const float64_t PI
Definition: Math.h:2055

SHOGUN Machine Learning Toolbox - Documentation