SHOGUN  4.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GaussianKernel.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) 1999-2010 Soeren Sonnenburg
8  * Written (W) 2011 Abhinav Maurya
9  * Written (W) 2012 Heiko Strathmann
10  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
11  * Copyright (C) 2010 Berlin Institute of Technology
12  */
13 
14 #include <shogun/lib/common.h>
15 #include <shogun/base/Parameter.h>
18 #include <shogun/io/SGIO.h>
19 
20 using namespace shogun;
21 
23 {
24  init();
25 }
26 
28 {
29  init();
30  set_width(w);
31 }
32 
34  float64_t w, int32_t size) : CDotKernel(size)
35 {
36  init();
37  set_width(w);
38  init(l,r);
39 }
40 
42 {
43  cleanup();
44 }
45 
47 {
48  if (kernel->get_kernel_type()!=K_GAUSSIAN)
49  {
50  SG_SERROR("CGaussianKernel::obtain_from_generic(): provided kernel is "
51  "not of type CGaussianKernel!\n");
52  }
53 
54  /* since an additional reference is returned */
55  SG_REF(kernel);
56  return (CGaussianKernel*)kernel;
57 }
58 
59 #include <typeinfo>
61 {
62  // TODO: remove this after all the classes get shallow_copy properly implemented
63  // this assert is to avoid any subclass of CGaussianKernel accidentally called
64  // with the implement here
65  ASSERT(typeid(*this) == typeid(CGaussianKernel))
67  if (lhs)
68  {
69  ker->init(lhs, rhs);
70  }
71  return ker;
72 }
73 
75 {
76  if (sq_lhs != sq_rhs)
77  SG_FREE(sq_rhs);
78  sq_rhs = NULL;
79 
80  SG_FREE(sq_lhs);
81  sq_lhs = NULL;
82 
84 }
85 
86 void CGaussianKernel::precompute_squared_helper(float64_t* &buf, CDotFeatures* df)
87 {
88  ASSERT(df)
89  int32_t num_vec=df->get_num_vectors();
90  buf=SG_MALLOC(float64_t, num_vec);
91 
92  for (int32_t i=0; i<num_vec; i++)
93  buf[i]=df->dot(i,df, i);
94 }
95 
97 {
99  cleanup();
100 
101  CDotKernel::init(l, r);
102  precompute_squared();
103  return init_normalizer();
104 }
105 
106 float64_t CGaussianKernel::compute(int32_t idx_a, int32_t idx_b)
107 {
108  if (!m_compact)
109  {
110  float64_t result=distance(idx_a,idx_b);
111  return CMath::exp(-result);
112  }
113 
114  int32_t len_features, power;
115  len_features=((CDotFeatures*) lhs)->get_dim_feature_space();
116  power=(len_features%2==0) ? (len_features+1):len_features;
117 
118  float64_t result=distance(idx_a,idx_b);
119  float64_t result_multiplier=1-(sqrt(result))/3;
120 
121  if (result_multiplier<=0)
122  result_multiplier=0;
123  else
124  result_multiplier=pow(result_multiplier, power);
125 
126  return result_multiplier*exp(-result);
127 }
128 
130 {
132  precompute_squared();
133 }
134 
135 void CGaussianKernel::precompute_squared()
136 {
137  if (!lhs || !rhs)
138  return;
139 
140  precompute_squared_helper(sq_lhs, (CDotFeatures*) lhs);
141 
142  if (lhs==rhs)
143  sq_rhs=sq_lhs;
144  else
145  precompute_squared_helper(sq_rhs, (CDotFeatures*) rhs);
146 }
147 
149  const TParameter* param, index_t index)
150 {
151  REQUIRE(lhs && rhs, "Features not set!\n")
152 
153  if (!strcmp(param->m_name, "width"))
154  {
156 
157  for (int j=0; j<num_lhs; j++)
158  for (int k=0; k<num_rhs; k++)
159  {
160  float64_t element=distance(j,k);
161  derivative(j,k)=exp(-element)*element/width;
162  }
163 
164  return derivative;
165  }
166  else
167  {
168  SG_ERROR("Can't compute derivative wrt %s parameter\n", param->m_name);
169  return SGMatrix<float64_t>();
170  }
171 }
172 
173 void CGaussianKernel::init()
174 {
175  set_width(1.0);
176  set_compact_enabled(false);
177  sq_lhs=NULL;
178  sq_rhs=NULL;
179  SG_ADD(&width, "width", "Kernel width", MS_AVAILABLE, GRADIENT_AVAILABLE);
180  SG_ADD(&m_compact, "compact", "Compact enabled option", MS_AVAILABLE);
181 }
182 
183 float64_t CGaussianKernel::distance(int32_t idx_a, int32_t idx_b)
184 {
185  return (sq_lhs[idx_a]+sq_rhs[idx_b]-2*CDotKernel::compute(idx_a,idx_b))/width;
186 }

SHOGUN Machine Learning Toolbox - Documentation