SHOGUN  6.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
GaussianARDKernel.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) 2015 Wu Lin
8  * Written (W) 2012 Jacob Walker
9  *
10  * Adapted from WeightedDegreeRBFKernel.cpp
11  */
12 
16 
17 using namespace shogun;
18 
20 {
21  init();
22 }
23 
25 {
26 }
27 
28 void CGaussianARDKernel::init()
29 {
32  SG_ADD(&m_sq_lhs, "sq_lhs", "squared left-hand side", MS_NOT_AVAILABLE);
33  SG_ADD(&m_sq_rhs, "sq_rhs", "squared right-hand side", MS_NOT_AVAILABLE);
34 }
35 
36 float64_t CGaussianARDKernel::distance(int32_t idx_a, int32_t idx_b)
37 {
38  float64_t result=0.0;
39  REQUIRE(lhs, "Left features (lhs) not set!\n")
40  REQUIRE(rhs, "Right features (rhs) not set!\n")
41 
42  if (lhs==rhs && idx_a==idx_b)
43  return result;
44 
45  if (m_ARD_type==KT_SCALAR)
46  {
47  result=(m_sq_lhs[idx_a]+m_sq_rhs[idx_b]-2.0*CDotKernel::compute(idx_a,idx_b));
48  result*=CMath::exp(2.0*m_log_weights[0]);
49  }
50  else
51  {
54  avec=linalg::add(avec, bvec, 1.0, -1.0);
55  result=compute_helper(avec, avec);
56  }
57  return result * 0.5;
58 }
59 
61  : CExponentialARDKernel(size)
62 {
63  init();
64 }
65 
67  CDotFeatures* r, int32_t size)
68  : CExponentialARDKernel(size)
69 {
70  init();
71 }
72 
73 bool CGaussianARDKernel::init(CFeatures* l, CFeatures* r)
74 {
75  bool status=CExponentialARDKernel::init(l,r);
76 
77  if (m_ARD_type==KT_SCALAR)
79 
80  return status;
81 }
82 
84 {
85  REQUIRE(df, "Features not set\n")
86  int32_t num_vec=df->get_num_vectors();
87  SGVector<float64_t> sq(num_vec);
88  for (int32_t i=0; i<num_vec; i++)
89  sq[i]=df->dot(i,df, i);
90  return sq;
91 }
92 
94 {
95  if (!lhs || !rhs)
96  return;
98 
99  if (lhs==rhs)
101  else
103 }
104 
105 
107 {
108  if (kernel->get_kernel_type()!=K_GAUSSIANARD)
109  {
110  SG_SERROR("Provided kernel is not of type CGaussianARDKernel!\n");
111  }
112 
113  /* since an additional reference is returned */
114  SG_REF(kernel);
115  return (CGaussianARDKernel*)kernel;
116 }
117 
119 {
120  SGMatrix<float64_t> left;
121  SGMatrix<float64_t> left_transpose;
122  float64_t scalar_weight=1.0;
123  if (m_ARD_type==KT_SCALAR)
124  {
125  left=SGMatrix<float64_t>(avec.vector,1,avec.vlen,false);
126  scalar_weight=CMath::exp(m_log_weights[0]);
127  }
128  else if(m_ARD_type==KT_FULL || m_ARD_type==KT_DIAG)
129  {
130  left_transpose=get_weighted_vector(avec);
131  left=SGMatrix<float64_t>(left_transpose.matrix,1,left_transpose.num_rows,false);
132  }
133  else
134  SG_ERROR("Unsupported ARD type\n");
135  SGMatrix<float64_t> right=compute_right_product(bvec, scalar_weight);
136  SGMatrix<float64_t> res=linalg::matrix_prod(left, right);
137  return res[0]*scalar_weight;
138 }
139 
142 {
143  float64_t result=0.0;
144 
145  if(m_ARD_type==KT_DIAG)
146  result=2.0*avec[index]*bvec[index]*CMath::exp(2.0*m_log_weights[index]);
147  else
148  {
150 
151  if (m_ARD_type==KT_SCALAR)
152  {
153  SGMatrix<float64_t> left(avec.vector,1,avec.vlen,false);
154  SGMatrix<float64_t> right(bvec.vector,bvec.vlen,1,false);
155  res=linalg::matrix_prod(left, right);
156  result=2.0*res[0]*CMath::exp(2.0*m_log_weights[0]);
157  }
158  else if(m_ARD_type==KT_FULL)
159  {
160  int32_t row_index=0;
161  int32_t col_index=index;
162  int32_t offset=m_weights_rows;
163  int32_t total_offset=0;
164  while(col_index>=offset && offset>0)
165  {
166  col_index-=offset;
167  total_offset+=offset;
168  offset--;
169  row_index++;
170  }
171  col_index+=row_index;
172 
173  SGVector<float64_t> row_vec=SGVector<float64_t>(m_log_weights.vector+total_offset,m_weights_rows-row_index,false);
174  row_vec[0]=CMath::exp(row_vec[0]);
175 
176  SGMatrix<float64_t> row_vec_r(row_vec.vector,row_vec.vlen,1,false);
177  SGMatrix<float64_t> left(avec.vector+row_index,1,avec.vlen-row_index,false);
178 
179  res=linalg::matrix_prod(left, row_vec_r);
180  result=res[0]*bvec[col_index];
181 
182  SGMatrix<float64_t> row_vec_l(row_vec.vector,1,row_vec.vlen,false);
183  SGMatrix<float64_t> right(bvec.vector+row_index,bvec.vlen-row_index,1,false);
184 
185  res=linalg::matrix_prod(row_vec_l, right);
186  result+=res[0]*avec[col_index];
187 
188  if(row_index==col_index)
189  result*=row_vec[0];
190  row_vec[0]=CMath::log(row_vec[0]);
191  }
192  else
193  {
194  SG_ERROR("Unsupported ARD type\n");
195  }
196 
197  }
198  return result*scale;
199 }
200 
201 
203  const TParameter* param, index_t index)
204 {
205  REQUIRE(param, "Param not set\n");
206  REQUIRE(lhs , "Left features not set!\n");
207  REQUIRE(rhs, "Right features not set!\n");
208 
209  if (lhs==rhs)
210  {
211  if (!strcmp(param->m_name, "log_weights"))
212  {
213  SGVector<float64_t> derivative(num_lhs);
214  derivative.zero();
215  return derivative;
216  }
217  }
218  else
219  {
220  int32_t length=CMath::min(num_lhs, num_rhs);
221  SGVector<float64_t> derivative(length);
223  for (index_t j=0; j<length; j++)
224  {
225  if (!strcmp(param->m_name, "log_weights") )
226  {
227  if (m_ARD_type==KT_SCALAR)
228  {
229  float64_t dist=distance(j,j);
230  derivative[j]=CMath::exp(-dist)*(-dist*2.0);
231  }
232  else
233  {
236  derivative[j]=get_parameter_gradient_helper(param,index,j,j,avec,bvec);
237  }
238 
239  }
240  }
241  return derivative;
242  }
243 
244  SG_ERROR("Can't compute derivative wrt %s parameter\n", param->m_name);
245  return SGVector<float64_t>();
246 }
247 
248 
250  const TParameter* param, index_t index, int32_t idx_a,
251  int32_t idx_b, SGVector<float64_t> avec, SGVector<float64_t> bvec)
252 {
253  REQUIRE(param, "Param not set\n");
254 
255  if (!strcmp(param->m_name, "log_weights"))
256  {
257  bvec=linalg::add(avec, bvec, 1.0, -1.0);
258  float64_t scale=-kernel(idx_a,idx_b)/2.0;
259  return compute_gradient_helper(bvec, bvec, scale, index);
260  }
261  else
262  {
263  SG_ERROR("Can't compute derivative wrt %s parameter\n", param->m_name);
264  return 0.0;
265  }
266 }
267 
269  const TParameter* param, index_t index)
270 {
271  REQUIRE(param, "Param not set\n");
272  REQUIRE(lhs , "Left features not set!\n");
273  REQUIRE(rhs, "Right features not set!\n");
274 
275  if (!strcmp(param->m_name, "log_weights"))
276  {
277  SGMatrix<float64_t> derivative(num_lhs, num_rhs);
279  for (index_t j=0; j<num_lhs; j++)
280  {
282  for (index_t k=0; k<num_rhs; k++)
283  {
284  if (m_ARD_type==KT_SCALAR)
285  {
286  float64_t dist=distance(j,k);
287  derivative(j,k)=CMath::exp(-dist)*(-dist*2.0);
288  }
289  else
290  {
292  derivative(j,k)=get_parameter_gradient_helper(param,index,j,k,avec,bvec);
293  }
294  }
295  }
296  return derivative;
297  }
298  else
299  {
300  SG_ERROR("Can't compute derivative wrt %s parameter\n", param->m_name);
301  return SGMatrix<float64_t>();
302  }
303 }
virtual SGMatrix< float64_t > get_parameter_gradient(const TParameter *param, index_t index=-1)
SGVector< float64_t > m_log_weights
virtual float64_t compute_gradient_helper(SGVector< float64_t > avec, SGVector< float64_t > bvec, float64_t scale, index_t index)
int32_t index_t
Definition: common.h:72
int32_t num_rhs
number of feature vectors on right hand side
virtual float64_t distance(int32_t idx_a, int32_t idx_b)
virtual SGVector< float64_t > get_parameter_gradient_diagonal(const TParameter *param, index_t index=-1)
SGVector< float64_t > m_sq_rhs
static CGaussianARDKernel * obtain_from_generic(CKernel *kernel)
virtual SGMatrix< float64_t > compute_right_product(SGVector< float64_t >vec, float64_t &scalar_weight)
void scale(SGVector< T > &a, SGVector< T > &result, T alpha=1)
virtual float64_t dot(int32_t vec_idx1, CDotFeatures *df, int32_t vec_idx2)=0
parameter struct
virtual int32_t get_num_vectors() const =0
void add(SGVector< T > &a, SGVector< T > &b, SGVector< T > &result, T alpha=1, T beta=1)
#define SG_ERROR(...)
Definition: SGIO.h:128
#define REQUIRE(x,...)
Definition: SGIO.h:205
float64_t kernel(int32_t idx_a, int32_t idx_b)
virtual float64_t get_parameter_gradient_helper(const TParameter *param, index_t index, int32_t idx_a, int32_t idx_b, SGVector< float64_t > avec, SGVector< float64_t > bvec)
virtual float64_t compute(int32_t idx_a, int32_t idx_b)
Definition: DotKernel.h:134
Features that support dot products among other operations.
Definition: DotFeatures.h:44
SGMatrix< float64_t > get_weighted_vector(SGVector< float64_t > vec)
#define SG_REF(x)
Definition: SGObject.h:52
index_t num_rows
Definition: SGMatrix.h:463
Gaussian Kernel with Automatic Relevance Detection computed on CDotFeatures.
index_t vlen
Definition: SGVector.h:545
virtual float64_t compute_helper(SGVector< float64_t > avec, SGVector< float64_t >bvec)
double float64_t
Definition: common.h:60
virtual SGVector< float64_t > get_feature_vector(int32_t idx, CFeatures *hs)
int32_t num_lhs
number of feature vectors on left hand side
SGVector< float64_t > m_sq_lhs
void matrix_prod(SGMatrix< T > &A, SGVector< T > &b, SGVector< T > &result, bool transpose=false)
virtual void check_weight_gradient_index(index_t index)
CFeatures * rhs
feature vectors to occur on right hand side
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
virtual EKernelType get_kernel_type()=0
CFeatures * lhs
feature vectors to occur on left hand side
The class Features is the base class of all feature objects.
Definition: Features.h:68
static T min(T a, T b)
Definition: Math.h:153
#define SG_SERROR(...)
Definition: SGIO.h:178
static float64_t exp(float64_t x)
Definition: Math.h:616
static float64_t log(float64_t v)
Definition: Math.h:917
The Kernel base class.
virtual SGVector< float64_t > precompute_squared_helper(CDotFeatures *df)
#define SG_ADD(...)
Definition: SGObject.h:94
Exponential Kernel with Automatic Relevance Detection computed on CDotFeatures.

SHOGUN Machine Learning Toolbox - Documentation