SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ProductKernel.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  * Copyright (C) 2012 Jacob Walker
8  *
9  * Code adapted from CCombinedKernel
10  */
11 
14 
15 using namespace shogun;
16 
18 : CKernel(size)
19 {
20  init();
21 
22  SG_INFO("Product kernel created (%p)\n", this) ;
23 }
24 
26 {
27  cleanup();
29 
30  SG_INFO("Product kernel deleted (%p).\n", this);
31 }
32 
33 //Adapted from CCombinedKernel
34 bool CProductKernel::init(CFeatures* l, CFeatures* r)
35 {
36  CKernel::init(l,r);
41 
42  CFeatures* lf=NULL;
43  CFeatures* rf=NULL;
44  CKernel* k=NULL;
45 
46  bool result=true;
47 
48  CListElement* lfc = NULL;
49  CListElement* rfc = NULL;
50  lf=((CCombinedFeatures*) l)->get_first_feature_obj(lfc);
51  rf=((CCombinedFeatures*) r)->get_first_feature_obj(rfc);
52  CListElement* current = NULL;
53  k=get_first_kernel(current);
54 
55  while ( result && k )
56  {
57  // skip over features - the custom kernel does not need any
58  if (k->get_kernel_type() != K_CUSTOM)
59  {
60  if (!lf || !rf)
61  {
62  SG_UNREF(lf);
63  SG_UNREF(rf);
64  SG_UNREF(k);
65  SG_ERROR( "ProductKernel: Number of features/kernels does not match - bailing out\n");
66  }
67 
68  SG_DEBUG( "Initializing 0x%p - \"%s\"\n", this, k->get_name());
69  result=k->init(lf,rf);
70  SG_UNREF(lf);
71  SG_UNREF(rf);
72 
73  lf=((CCombinedFeatures*) l)->get_next_feature_obj(lfc) ;
74  rf=((CCombinedFeatures*) r)->get_next_feature_obj(rfc) ;
75  }
76  else
77  {
78  SG_DEBUG( "Initializing 0x%p - \"%s\" (skipping init, this is a CUSTOM kernel)\n", this, k->get_name());
79  if (!k->has_features())
80  SG_ERROR("No kernel matrix was assigned to this Custom kernel\n");
81  if (k->get_num_vec_lhs() != num_lhs)
82  SG_ERROR("Number of lhs-feature vectors (%d) not match with number of rows (%d) of custom kernel\n", num_lhs, k->get_num_vec_lhs());
83  if (k->get_num_vec_rhs() != num_rhs)
84  SG_ERROR("Number of rhs-feature vectors (%d) not match with number of cols (%d) of custom kernel\n", num_rhs, k->get_num_vec_rhs());
85  }
86 
87  SG_UNREF(k);
88  k=get_next_kernel(current) ;
89  }
90 
91  if (!result)
92  {
93  SG_INFO( "ProductKernel: Initialising the following kernel failed\n");
94  if (k)
95  k->list_kernel();
96  else
97  SG_INFO( "<NULL>\n");
98  return false;
99  }
100 
101  if ((lf!=NULL) || (rf!=NULL) || (k!=NULL))
102  {
103  SG_UNREF(lf);
104  SG_UNREF(rf);
105  SG_UNREF(k);
106  SG_ERROR( "ProductKernel: Number of features/kernels does not match - bailing out\n");
107  }
108 
109  initialized=true;
110  return true;
111 }
112 
113 //Adapted from CCombinedKernel
115 {
116  CListElement* current = NULL ;
117  CKernel* k=get_first_kernel(current);
118 
119  while (k)
120  {
121  if (k->get_kernel_type() != K_CUSTOM)
122  k->remove_lhs();
123 
124  SG_UNREF(k);
125  k=get_next_kernel(current);
126  }
128 
129  num_lhs=0;
130 }
131 
132 //Adapted from CCombinedKernel
134 {
135  CListElement* current = NULL ;
136  CKernel* k=get_first_kernel(current);
137 
138  while (k)
139  {
140  if (k->get_kernel_type() != K_CUSTOM)
141  k->remove_rhs();
142  SG_UNREF(k);
143  k=get_next_kernel(current);
144  }
146 
147  num_rhs=0;
148 }
149 
150 //Adapted from CCombinedKernel
152 {
153  CListElement* current = NULL ;
154  CKernel* k=get_first_kernel(current);
155 
156  while (k)
157  {
158  if (k->get_kernel_type() != K_CUSTOM)
159  k->remove_lhs_and_rhs();
160  SG_UNREF(k);
161  k=get_next_kernel(current);
162  }
163 
165 
166  num_lhs=0;
167  num_rhs=0;
168 }
169 
170 //Adapted from CCombinedKernel
172 {
173  CListElement* current = NULL ;
174  CKernel* k=get_first_kernel(current);
175 
176  while (k)
177  {
178  k->cleanup();
179  SG_UNREF(k);
180  k=get_next_kernel(current);
181  }
182 
184 
185  num_lhs=0;
186  num_rhs=0;
187 }
188 
189 //Adapted from CCombinedKernel
191 {
192  CKernel* k;
193 
194  SG_INFO( "BEGIN PRODUCT KERNEL LIST - ");
195  this->list_kernel();
196 
197  CListElement* current = NULL ;
198  k=get_first_kernel(current);
199  while (k)
200  {
201  k->list_kernel();
202  SG_UNREF(k);
203  k=get_next_kernel(current);
204  }
205  SG_INFO( "END PRODUCT KERNEL LIST - ");
206 }
207 
208 //Adapted from CCombinedKernel
209 float64_t CProductKernel::compute(int32_t x, int32_t y)
210 {
211  float64_t result=1;
212  CListElement* current = NULL ;
213  CKernel* k=get_first_kernel(current);
214  while (k)
215  {
216  result *= k->get_combined_kernel_weight() * k->kernel(x,y);
217  SG_UNREF(k);
218  k=get_next_kernel(current);
219  }
220 
221  return result;
222 }
223 
224 //Adapted from CCombinedKernel
225 
227 {
228  CKernel* k = get_first_kernel();
229 
230  if (!k)
231  return false;
232 
233  CList* new_kernel_list = new CList(true);
234 
235  while(k)
236  {
237  new_kernel_list->append_element(new CCustomKernel(k));
238  SG_UNREF(k);
239  k = get_next_kernel();
240  }
241 
243  kernel_list=new_kernel_list;
245 
246  return true;
247 }
248 
249 void CProductKernel::init()
250 {
251  initialized=false;
252 
254  kernel_list=new CList(true);
256 
257  SG_ADD((CSGObject**) &kernel_list, "kernel_list", "List of kernels.",
258  MS_AVAILABLE);
259  SG_ADD(&initialized, "initialized", "Whether kernel is ready to be used.",
261 }
262 
264  CSGObject* obj, index_t index)
265 {
266 
267  CListElement* current = NULL ;
268  CKernel* k = get_first_kernel(current);
269  SGMatrix<float64_t> temp_kernel = k->get_kernel_matrix();
270 
271  bool found_derivative = false;
272 
273  for (index_t g = 0; g < temp_kernel.num_rows; g++)
274  {
275  for (int h = 0; h < temp_kernel.num_cols; h++)
276  temp_kernel(g,h) = 1.0;
277  }
278 
279  while(k)
280  {
281  SGMatrix<float64_t> cur_matrix = k->get_kernel_matrix();
282  SGMatrix<float64_t> derivative =
283  k->get_parameter_gradient(param, obj, index);
284 
285  if (derivative.num_cols*derivative.num_rows > 0)
286  {
287  found_derivative = true;
288  for (index_t g = 0; g < derivative.num_rows; g++)
289  {
290  for (index_t h = 0; h < derivative.num_cols; h++)
291  temp_kernel(g,h) *= derivative(g,h);
292  }
293 
294  }
295 
296  else
297  {
298  for (index_t g = 0; g < cur_matrix.num_rows; g++)
299  {
300  for (index_t h = 0; h < cur_matrix.num_cols; h++)
301  temp_kernel(g,h) *= cur_matrix(g,h);
302  }
303 
304  }
305 
306  SG_UNREF(k);
307  k = get_next_kernel(current);
308  }
309 
310  if (found_derivative)
311  return temp_kernel;
312 
313  else
314  return SGMatrix<float64_t>();
315 }

SHOGUN Machine Learning Toolbox - Documentation