SHOGUN  4.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ProbitLikelihood.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) The Shogun Machine Learning Toolbox
3  * Written (W) 2013 Roman Votyakov
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are those
27  * of the authors and should not be interpreted as representing official policies,
28  * either expressed or implied, of the Shogun Development Team.
29  *
30  */
32 
33 #ifdef HAVE_EIGEN3
34 
38 
39 using namespace shogun;
40 using namespace Eigen;
41 
43 {
44 }
45 
47 {
48 }
49 
51  SGVector<float64_t> mu, SGVector<float64_t> s2, const CLabels* lab) const
52 {
53  SGVector<float64_t> lp=get_log_zeroth_moments(mu, s2, lab);
54  Map<VectorXd> eigen_lp(lp.vector, lp.vlen);
55 
57  Map<VectorXd> eigen_r(r.vector, r.vlen);
58 
59  // evaluate predictive mean: ymu=2*p-1
60  eigen_r=2.0*eigen_lp.array().exp()-1.0;
61 
62  return r;
63 }
64 
66  SGVector<float64_t> mu, SGVector<float64_t> s2, const CLabels* lab) const
67 {
68  SGVector<float64_t> lp=get_log_zeroth_moments(mu, s2, lab);
69  Map<VectorXd> eigen_lp(lp.vector, lp.vlen);
70 
72  Map<VectorXd> eigen_r(r.vector, r.vlen);
73 
74  // evaluate predictive variance: ys2=1-(2*p-1).^2
75  eigen_r=1-(2.0*eigen_lp.array().exp()-1.0).square();
76 
77  return r;
78 }
79 
81  SGVector<float64_t> func) const
82 {
83  // check the parameters
84  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
86  "Labels must be type of CBinaryLabels\n")
87  REQUIRE(lab->get_num_labels()==func.vlen, "Number of labels must match "
88  "length of the function vector\n")
89 
90  SGVector<float64_t> y=((CBinaryLabels*)lab)->get_labels();
91  Map<VectorXd> eigen_y(y.vector, y.vlen);
92 
93  Map<VectorXd> eigen_f(func.vector, func.vlen);
94 
95  SGVector<float64_t> r(func.vlen);
96  Map<VectorXd> eigen_r(r.vector, r.vlen);
97 
98  // compute log pobability: log(normal_cdf(f.*y))
99  eigen_r=eigen_y.cwiseProduct(eigen_f);
100 
101  for (index_t i=0; i<eigen_r.size(); i++)
102  eigen_r[i]=CStatistics::lnormal_cdf(eigen_r[i]);
103 
104  return r;
105 }
106 
108  const CLabels* lab, SGVector<float64_t> func, index_t i) const
109 {
110  // check the parameters
111  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
113  "Labels must be type of CBinaryLabels\n")
114  REQUIRE(lab->get_num_labels()==func.vlen, "Number of labels must match "
115  "length of the function vector\n")
116  REQUIRE(i>=1 && i<=3, "Index for derivative should be 1, 2 or 3\n")
117 
118  SGVector<float64_t> y=((CBinaryLabels*)lab)->get_labels();
119  Map<VectorXd> eigen_y(y.vector, y.vlen);
120 
121  Map<VectorXd> eigen_f(func.vector, func.vlen);
122 
123  SGVector<float64_t> dlp(func.vlen);
124  Map<VectorXd> eigen_dlp(dlp.vector, dlp.vlen);
125 
126  VectorXd eigen_yf=eigen_y.cwiseProduct(eigen_f);
127 
128  for (index_t j=0; j<eigen_yf.size(); j++)
129  {
130  float64_t v = eigen_yf[j];
132  {
133  //dlp( id2) = abs(den./num) * sqrt(2/pi); % strictly positive first derivative
134  eigen_dlp[j]=CMath::sqrt(2.0/CMath::PI)
136  }
137  else
138  {
139  //dlp(~id2) = exp(-z(~id2).*z(~id2)/2-lp(~id2))/sqrt(2*pi); % safe computation
140  eigen_dlp[j]=CMath::exp(-v*v/2.0-CStatistics::lnormal_cdf(v))
141  /CMath::sqrt(2.0*CMath::PI);
142  }
143  }
144 
145  SGVector<float64_t> r(func.vlen);
146  Map<VectorXd> eigen_r(r.vector, r.vlen);
147 
148  // compute derivatives of log probability wrt f
149 
150  if (i==1)
151  eigen_r=eigen_dlp;
152  else
153  //d2lp = -dlp.*abs(z+dlp); % strictly negative second derivative
154  eigen_r=(-eigen_dlp.array()*((eigen_yf.array()+eigen_dlp.array()).abs().array())).matrix();
155 
156  if (i==3)
157  //d3lp = -d2lp.*abs(z+2*dlp)-dlp; % strictly positive third derivative
158  eigen_r=(-eigen_r.array()*((eigen_yf.array()+2.0*eigen_dlp.array()).abs().array())
159  -eigen_dlp.array()).matrix();
160 
161  if (i==1 || i==3)
162  {
163  //varargout{2} = y.*varargout{2}
164  //varargout{4} = y.*varargout{4}
165  eigen_r=(eigen_r.array()*eigen_y.array()).matrix();
166  }
167 
168  return r;
169 }
170 
172  SGVector<float64_t> mu, SGVector<float64_t> s2, const CLabels* lab) const
173 {
175 
176  if (lab)
177  {
178  REQUIRE((mu.vlen==s2.vlen) && (mu.vlen==lab->get_num_labels()),
179  "Length of the vector of means (%d), length of the vector of "
180  "variances (%d) and number of labels (%d) should be the same\n",
181  mu.vlen, s2.vlen, lab->get_num_labels())
183  "Labels must be type of CBinaryLabels\n")
184 
185  y=((CBinaryLabels*)lab)->get_labels();
186  }
187  else
188  {
189  REQUIRE(mu.vlen==s2.vlen, "Length of the vector of means (%d) and "
190  "length of the vector of variances (%d) should be the same\n",
191  mu.vlen, s2.vlen)
192 
194  y.set_const(1.0);
195  }
196 
197  Map<VectorXd> eigen_y(y.vector, y.vlen);
198  Map<VectorXd> eigen_mu(mu.vector, mu.vlen);
199  Map<VectorXd> eigen_s2(s2.vector, s2.vlen);
200 
202  Map<VectorXd> eigen_r(r.vector, r.vlen);
203 
204  // compute: lp=log(normal_cdf((mu.*y)./sqrt(1+sigma^2)))
205  eigen_r=eigen_mu.array()*eigen_y.array()/((1.0+eigen_s2.array()).sqrt());
206 
207  for (index_t i=0; i<eigen_r.size(); i++)
208  eigen_r[i]=CStatistics::lnormal_cdf(eigen_r[i]);
209 
210  return r;
211 }
212 
214  SGVector<float64_t> s2, const CLabels *lab, index_t i) const
215 {
216  // check the parameters
217  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
218  REQUIRE((mu.vlen==s2.vlen) && (mu.vlen==lab->get_num_labels()),
219  "Length of the vector of means (%d), length of the vector of "
220  "variances (%d) and number of labels (%d) should be the same\n",
221  mu.vlen, s2.vlen, lab->get_num_labels())
222  REQUIRE(i>=0 && i<=mu.vlen, "Index (%d) out of bounds!\n", i)
224  "Labels must be type of CBinaryLabels\n")
225 
226  SGVector<float64_t> y=((CBinaryLabels*)lab)->get_labels();
227 
228  float64_t z=y[i]*mu[i]/CMath::sqrt(1.0+s2[i]);
229 
230  // compute ncdf=normal_cdf(z)
232 
233  // compute npdf=normal_pdf(z)=(1/sqrt(2*pi))*exp(-z.^2/2)
234  float64_t npdf=(1.0/CMath::sqrt(2.0*CMath::PI))*CMath::exp(-0.5*CMath::sq(z));
235 
236  // compute the 1st moment: E[x] = mu + (y*s2*N(z))/(Phi(z)*sqrt(1+s2))
237  float64_t Ex=mu[i]+(npdf/ncdf)*(y[i]*s2[i])/CMath::sqrt(1.0+s2[i]);
238 
239  return Ex;
240 }
241 
243  SGVector<float64_t> s2, const CLabels *lab, index_t i) const
244 {
245  // check the parameters
246  REQUIRE(lab, "Labels are required (lab should not be NULL)\n")
247  REQUIRE((mu.vlen==s2.vlen) && (mu.vlen==lab->get_num_labels()),
248  "Length of the vector of means (%d), length of the vector of "
249  "variances (%d) and number of labels (%d) should be the same\n",
250  mu.vlen, s2.vlen, lab->get_num_labels())
251  REQUIRE(i>=0 && i<=mu.vlen, "Index (%d) out of bounds!\n", i)
253  "Labels must be type of CBinaryLabels\n")
254 
255  SGVector<float64_t> y=((CBinaryLabels*)lab)->get_labels();
256 
257  float64_t z=y[i]*mu[i]/CMath::sqrt(1.0+s2[i]);
258 
259  // compute ncdf=normal_cdf(z)
261 
262  // compute npdf=normal_pdf(z)=(1/sqrt(2*pi))*exp(-z.^2/2)
263  float64_t npdf=(1.0/CMath::sqrt(2.0*CMath::PI))*CMath::exp(-0.5*CMath::sq(z));
264 
265  SGVector<float64_t> r(y.vlen);
266  Map<VectorXd> eigen_r(r.vector, r.vlen);
267 
268  // compute the 2nd moment:
269  // Var[x] = s2 - (s2^2*N(z))/((1+s2)*Phi(z))*(z+N(z)/Phi(z))
270  float64_t Var=s2[i]-(CMath::sq(s2[i])/(1.0+s2[i]))*(npdf/ncdf)*(z+(npdf/ncdf));
271 
272  return Var;
273 }
274 
275 #endif /* HAVE_EIGEN3 */
virtual ELabelType get_label_type() const =0
binary labels +1/-1
Definition: LabelTypes.h:18
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
static T sq(T x)
Definition: Math.h:450
Definition: SGMatrix.h:20
#define REQUIRE(x,...)
Definition: SGIO.h:206
static const float64_t ERFC_CASE2
Definition: Statistics.h:623
virtual SGVector< float64_t > get_predictive_variances(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab=NULL) const
static float64_t lnormal_cdf(float64_t x)
index_t vlen
Definition: SGVector.h:494
virtual SGVector< float64_t > get_log_probability_f(const CLabels *lab, SGVector< float64_t > func) const
double float64_t
Definition: common.h:50
virtual SGVector< float64_t > get_log_zeroth_moments(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab) const
virtual SGVector< float64_t > get_predictive_means(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab=NULL) const
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
static float64_t erfc8_weighted_sum(float64_t x)
static float64_t exp(float64_t x)
Definition: Math.h:621
virtual float64_t get_first_moment(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab, index_t i) const
static float64_t normal_cdf(float64_t x, float64_t std_dev=1)
Binary Labels for binary classification.
Definition: BinaryLabels.h:37
static float32_t sqrt(float32_t x)
Definition: Math.h:459
virtual SGVector< float64_t > get_log_probability_derivative_f(const CLabels *lab, SGVector< float64_t > func, index_t i) const
virtual float64_t get_second_moment(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab, index_t i) const
void set_const(T const_elem)
Definition: SGVector.cpp:152
static T abs(T a)
Definition: Math.h:179
static const float64_t PI
Definition: Math.h:2055

SHOGUN Machine Learning Toolbox - Documentation