SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 2012 Jacob Walker
8  *
9  * Adapted from WeightedDegreeRBFKernel.cpp
10  */
11 
12 #include <shogun/lib/common.h>
15 #include <shogun/io/SGIO.h>
16 
17 using namespace shogun;
18 
20 {
21  init();
22 }
23 
24 
26  : CLinearARDKernel(size), m_width(width)
27 {
28  init();
29 }
30 
32  CDenseFeatures<float64_t>* r, int32_t size, float64_t width)
33  : CLinearARDKernel(size), m_width(width)
34 {
35  init();
36 }
37 
38 bool CGaussianARDKernel::init(CFeatures* l, CFeatures* r)
39 {
40  return CLinearARDKernel::init(l,r);
41 }
42 
43 void CGaussianARDKernel::init()
44 {
45  m_width=1.0;
46 
47  SG_ADD(&m_width, "width", "Kernel width", MS_AVAILABLE, GRADIENT_AVAILABLE);
48 }
49 
51 {
52 }
53 
55 {
56  if (kernel->get_kernel_type()!=K_GAUSSIANARD)
57  {
58  SG_SERROR("Provided kernel is not of type CGaussianARDKernel!\n");
59  }
60 
61  /* since an additional reference is returned */
62  SG_REF(kernel);
63  return (CGaussianARDKernel*)kernel;
64 }
65 
66 float64_t CGaussianARDKernel::compute(int32_t idx_a, int32_t idx_b)
67 {
68  REQUIRE(lhs && rhs, "Features not set!\n")
69 
71  ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a);
73  ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b);
74 
75  REQUIRE(avec.vlen==bvec.vlen, "Number of right and left hand "
76  "features must be the same\n");
77 
78  float64_t result=0;
79 
80  for (index_t i = 0; i < avec.vlen; i++)
81  result += CMath::pow((avec[i]-bvec[i])*m_weights[i], 2);
82 
83  return CMath::exp(-result/m_width);
84 }
85 
87  const TParameter* param, index_t index)
88 {
89  REQUIRE(lhs && rhs, "Features not set!\n")
90 
91  if (!strcmp(param->m_name, "weights"))
92  {
94 
95  for (index_t j=0; j<num_lhs; j++)
96  {
97  for (index_t k=0; k<num_rhs; k++)
98  {
100  ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(j);
101  SGVector<float64_t> bvec=
102  ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(k);
103 
104  REQUIRE(avec.vlen==bvec.vlen, "Number of right and left hand "
105  "features must be the same\n");
106 
107  float64_t element=compute(j,k);
108  float64_t product=CMath::pow((avec[index]-bvec[index]), 2)
109  *(m_weights[index]/m_width);
110 
111  derivative(j,k)=-2*element*product;
112  }
113  }
114 
115  return derivative;
116  }
117  else if (!strcmp(param->m_name, "width"))
118  {
119  SGMatrix<float64_t> derivative(num_lhs, num_rhs);
120 
121  for (index_t j=0; j<num_lhs; j++)
122  {
123  for (index_t k=0; k<num_rhs; k++)
124  {
125  SGVector<float64_t> avec=
126  ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(j);
127  SGVector<float64_t> bvec=
128  ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(k);
129 
130  REQUIRE(avec.vlen==bvec.vlen, "Number of right and left hand "
131  "features must be the same\n");
132 
133  float64_t result=0;
134 
135  for (index_t i=0; i<avec.vlen; i++)
136  result+=CMath::pow((avec[i]-bvec[i])*m_weights[i], 2);
137 
138  derivative(j,k)=CMath::exp(-result/m_width)*
139  result/(m_width*m_width);
140  }
141  }
142 
143  return derivative;
144  }
145  else
146  {
147  SG_ERROR("Can't compute derivative wrt %s parameter\n", param->m_name);
148  return SGMatrix<float64_t>();
149  }
150 }

SHOGUN Machine Learning Toolbox - Documentation