SHOGUN  3.2.1
 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 {
19  init();
20 
21  SG_INFO("Product kernel created (%p)\n", this)
22 }
23 
25 {
26  cleanup();
28 
29  SG_INFO("Product kernel deleted (%p).\n", this)
30 }
31 
32 //Adapted from CCombinedKernel
33 bool CProductKernel::init(CFeatures* l, CFeatures* r)
34 {
35  CKernel::init(l,r);
40 
41  CFeatures* lf=NULL;
42  CFeatures* rf=NULL;
43  CKernel* k=NULL;
44 
45  bool result=true;
46 
47  index_t f_idx=0;
48  for (index_t k_idx=0; k_idx<get_num_subkernels() && result; k_idx++)
49  {
50  k=get_kernel(k_idx);
51  if (!k)
52  SG_ERROR("Kernel at position %d is NULL\n", k_idx);
53 
54  // skip over features - the custom kernel does not need any
55  if (k->get_kernel_type() != K_CUSTOM)
56  {
57  lf=((CCombinedFeatures*) l)->get_feature_obj(f_idx);
58  rf=((CCombinedFeatures*) r)->get_feature_obj(f_idx);
59  f_idx++;
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 
71  SG_UNREF(lf);
72  SG_UNREF(rf);
73 
74  if (!result)
75  break;
76  }
77  else
78  {
79  SG_DEBUG("Initializing 0x%p - \"%s\" (skipping init, this is a CUSTOM kernel)\n", this, k->get_name())
80  if (!k->has_features())
81  SG_ERROR("No kernel matrix was assigned to this Custom kernel\n")
82  if (k->get_num_vec_lhs() != num_lhs)
83  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())
84  if (k->get_num_vec_rhs() != num_rhs)
85  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())
86  }
87 
88  SG_UNREF(k);
89  }
90 
91  if (!result)
92  {
93  SG_INFO("ProductKernel: Initialising the following kernel failed\n")
94  if (k)
95  {
96  k->list_kernel();
97  SG_UNREF(k);
98  }
99  else
100  SG_INFO("<NULL>\n")
101  return false;
102  }
103 
104  if ( (f_idx!=((CCombinedFeatures*) l)->get_num_feature_obj()) ||
105  (f_idx!=((CCombinedFeatures*) r)->get_num_feature_obj()) )
106  SG_ERROR("ProductKernel: Number of features/kernels does not match - bailing out\n")
107 
108  initialized=true;
109  return true;
110 }
111 
112 //Adapted from CCombinedKernel
114 {
115  for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
116  {
117  CKernel* k=get_kernel(k_idx);
118  if (k->get_kernel_type() != K_CUSTOM)
119  k->remove_lhs();
120 
121  SG_UNREF(k);
122  }
124 
125  num_lhs=0;
126 }
127 
128 //Adapted from CCombinedKernel
130 {
131  for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
132  {
133  CKernel* k=get_kernel(k_idx);
134  if (k->get_kernel_type() != K_CUSTOM)
135  k->remove_rhs();
136  SG_UNREF(k);
137  }
139 
140  num_rhs=0;
141 }
142 
143 //Adapted from CCombinedKernel
145 {
146  for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
147  {
148  CKernel* k=get_kernel(k_idx);
149  if (k->get_kernel_type() != K_CUSTOM)
150  k->remove_lhs_and_rhs();
151  SG_UNREF(k);
152  }
153 
155 
156  num_lhs=0;
157  num_rhs=0;
158 }
159 
160 //Adapted from CCombinedKernel
162 {
163  for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
164  {
165  CKernel* k=get_kernel(k_idx);
166  k->cleanup();
167  SG_UNREF(k);
168  }
169 
171 
172  num_lhs=0;
173  num_rhs=0;
174 }
175 
176 //Adapted from CCombinedKernel
178 {
179  SG_INFO("BEGIN PRODUCT KERNEL LIST - ")
180  this->list_kernel();
181 
182  for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
183  {
184  CKernel* k=get_kernel(k_idx);
185  k->list_kernel();
186  SG_UNREF(k);
187  }
188  SG_INFO("END PRODUCT KERNEL LIST - ")
189 }
190 
191 //Adapted from CCombinedKernel
192 float64_t CProductKernel::compute(int32_t x, int32_t y)
193 {
194  float64_t result=1;
195  for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
196  {
197  CKernel* k=get_kernel(k_idx);
198  result *= k->get_combined_kernel_weight() * k->kernel(x,y);
199  SG_UNREF(k);
200  }
201 
202  return result;
203 }
204 
205 //Adapted from CCombinedKernel
207 {
208  if (get_num_subkernels()==0)
209  return false;
210 
211  CDynamicObjectArray* new_kernel_array=new CDynamicObjectArray();
212 
213  for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
214  {
215  CKernel* k=get_kernel(k_idx);
216  new_kernel_array->append_element(new CCustomKernel(k));
217  SG_UNREF(k);
218  }
219 
221  kernel_array=new_kernel_array;
223 
224  return true;
225 }
226 
227 void CProductKernel::init()
228 {
229  initialized=false;
230 
234 
235  SG_ADD((CSGObject**) &kernel_array, "kernel_array", "Array of kernels",
236  MS_AVAILABLE);
237  SG_ADD(&initialized, "initialized", "Whether kernel is ready to be used",
239 }
240 
242  const TParameter* param, index_t index)
243 {
244  CKernel* k=get_kernel(0);
245  SGMatrix<float64_t> temp_kernel=k->get_kernel_matrix();
246  SG_UNREF(k);
247 
248  bool found_derivative=false;
249 
250  for (index_t g=0; g<temp_kernel.num_rows; g++)
251  {
252  for (int h=0; h<temp_kernel.num_cols; h++)
253  temp_kernel(g,h)=1.0;
254  }
255 
256  for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
257  {
258  k=get_kernel(k_idx);
259  SGMatrix<float64_t> cur_matrix=k->get_kernel_matrix();
260  SGMatrix<float64_t> derivative=
261  k->get_parameter_gradient(param, index);
262 
263  if (derivative.num_cols*derivative.num_rows > 0)
264  {
265  found_derivative=true;
266  for (index_t g=0; g<derivative.num_rows; g++)
267  {
268  for (index_t h=0; h<derivative.num_cols; h++)
269  temp_kernel(g,h)*=derivative(g,h);
270  }
271  }
272  else
273  {
274  for (index_t g=0; g<cur_matrix.num_rows; g++)
275  {
276  for (index_t h=0; h<cur_matrix.num_cols; h++)
277  temp_kernel(g,h)*=cur_matrix(g,h);
278  }
279  }
280 
281  SG_UNREF(k);
282  }
283 
284  if (found_derivative)
285  return temp_kernel;
286  else
287  return SGMatrix<float64_t>();
288 }

SHOGUN Machine Learning Toolbox - Documentation