SHOGUN  v2.0.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  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
10  * Copyright (C) 2010 Berlin Institute of Technology
11  */
12 
13 #include <shogun/lib/common.h>
14 #include <shogun/base/Parameter.h>
18 #include <shogun/io/SGIO.h>
19 
20 using namespace shogun;
21 
23  : CDotKernel()
24 {
25  init();
26 }
27 
29 : CDotKernel(size)
30 {
31  init();
32  set_width(w);
33 }
34 
36  CDotFeatures* l, CDotFeatures* r, float64_t w, int32_t size)
37 : CDotKernel(size)
38 {
39  init();
40  set_width(w);
41  init(l,r);
42 }
43 
45 {
46  cleanup();
47 }
48 
49 #include <typeinfo>
51 {
52  // TODO: remove this after all the classes get shallow_copy properly implemented
53  // this assert is to avoid any subclass of CGaussianKernel accidentally called
54  // with the implement here
55  ASSERT(typeid(*this) == typeid(CGaussianKernel));
57  if (lhs)
58  {
59  ker->init(lhs, rhs);
60  }
61  return ker;
62 }
63 
65 {
66  if (sq_lhs != sq_rhs)
67  SG_FREE(sq_rhs);
68  sq_rhs = NULL;
69 
70  SG_FREE(sq_lhs);
71  sq_lhs = NULL;
72 
74 }
75 
76 void CGaussianKernel::precompute_squared_helper(float64_t* &buf, CDotFeatures* df)
77 {
78  ASSERT(df);
79  int32_t num_vec=df->get_num_vectors();
80  buf=SG_MALLOC(float64_t, num_vec);
81 
82  for (int32_t i=0; i<num_vec; i++)
83  buf[i]=df->dot(i,df, i);
84 }
85 
86 bool CGaussianKernel::init(CFeatures* l, CFeatures* r)
87 {
89  cleanup();
90 
91  CDotKernel::init(l, r);
92  precompute_squared();
93  return init_normalizer();
94 }
95 
96 float64_t CGaussianKernel::compute(int32_t idx_a, int32_t idx_b)
97 {
98  if (!m_compact)
99  {
100  float64_t result=sq_lhs[idx_a]+sq_rhs[idx_b]
101  -2*CDotKernel::compute(idx_a, idx_b);
102  return CMath::exp(-result/width);
103  }
104 
105  int32_t len_features, power;
106  len_features=((CDenseFeatures<float64_t>*) lhs)->get_num_features();
107  power=(len_features%2==0) ? (len_features+1):len_features;
108 
109  float64_t result=sq_lhs[idx_a]+sq_rhs[idx_b]-2*CDotKernel::compute(idx_a,idx_b);
110  float64_t result_multiplier=1-(sqrt(result/width))/3;
111 
112  if (result_multiplier<=0)
113  result_multiplier=0;
114  else
115  result_multiplier=pow(result_multiplier, power);
116 
117  return result_multiplier*exp(-result/width);
118 }
119 
121 {
123  precompute_squared();
124 }
125 
126 void CGaussianKernel::precompute_squared()
127 {
128  if (!lhs || !rhs)
129  return;
130 
131  precompute_squared_helper(sq_lhs, (CDotFeatures*) lhs);
132 
133  if (lhs==rhs)
134  sq_rhs=sq_lhs;
135  else
136  precompute_squared_helper(sq_rhs, (CDotFeatures*) rhs);
137 }
138 
140  CSGObject* obj, index_t index)
141 {
142 
143  if (strcmp(param->m_name, "width") == 0 && obj == this)
144  {
146 
147  for (int j = 0; j < num_lhs; j++)
148  {
149  for (int k = 0; k < num_rhs; k++)
150  {
151  float64_t element = sq_lhs[j]+sq_rhs[k]-2*CDotKernel::compute(j,k);
152  derivative(j,k) = exp(-element/width)*element/(width*width);
153  }
154  }
155 
156  return derivative;
157  }
158 
159  else
160  {
161  return SGMatrix<float64_t>(0,0);
162  }
163 }
164 
165 void CGaussianKernel::init()
166 {
167  set_width(1.0);
168  set_compact_enabled(false);
169  sq_lhs=NULL;
170  sq_rhs=NULL;
171  SG_ADD(&width, "width", "Kernel width.", MS_AVAILABLE);
172  SG_ADD(&m_compact, "compact", "Compact Enabled Option.", MS_AVAILABLE);
173 }

SHOGUN Machine Learning Toolbox - Documentation