SHOGUN  4.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
CustomKernel.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-2009 Soeren Sonnenburg
8  * Written (W) 2012 Heiko Strathmann
9  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
10  */
11 
12 #include <shogun/lib/common.h>
17 #include <shogun/io/SGIO.h>
18 
19 using namespace shogun;
20 
21 #ifdef HAVE_LINALG_LIB
23 
24 using namespace linalg;
25 #endif // HAVE_LINALG_LIB
26 
27 void CCustomKernel::init()
28 {
29  m_row_subset_stack=new CSubsetStack();
30  SG_REF(m_row_subset_stack)
31  m_col_subset_stack=new CSubsetStack();
32  SG_REF(m_col_subset_stack)
33  m_is_symmetric=false;
34  m_free_km=true;
35 
36  SG_ADD((CSGObject**)&m_row_subset_stack, "row_subset_stack",
37  "Subset stack of rows", MS_NOT_AVAILABLE);
38  SG_ADD((CSGObject**)&m_col_subset_stack, "col_subset_stack",
39  "Subset stack of columns", MS_NOT_AVAILABLE);
40  SG_ADD(&m_free_km, "free_km", "Whether kernel matrix should be freed in "
41  "destructor", MS_NOT_AVAILABLE);
42  SG_ADD(&m_is_symmetric, "is_symmetric", "Whether kernel matrix is symmetric",
43  MS_NOT_AVAILABLE);
44  SG_ADD(&kmatrix, "kmatrix", "Kernel matrix.", MS_NOT_AVAILABLE);
45  SG_ADD(&upper_diagonal, "upper_diagonal", "Upper diagonal", MS_NOT_AVAILABLE);
46 }
47 
49 : CKernel(10), kmatrix(), upper_diagonal(false)
50 {
51  SG_DEBUG("created CCustomKernel\n")
52  init();
53 }
54 
56 : CKernel(10)
57 {
58  SG_DEBUG("created CCustomKernel\n")
59  init();
60 
61  /* if constructed from a custom kernel, use same kernel matrix */
62  if (k->get_kernel_type()==K_CUSTOM)
63  {
64  CCustomKernel* casted=(CCustomKernel*)k;
67  m_free_km=false;
68  }
69  else
70  {
73  }
74 }
75 
77 : CKernel(10), upper_diagonal(false)
78 {
79  SG_DEBUG("Entering\n")
80  init();
82  SG_DEBUG("Leaving\n")
83 }
84 
86 : CKernel(10), upper_diagonal(false)
87 {
88  SG_DEBUG("Entering\n")
89  init();
91  SG_DEBUG("Leaving\n")
92 }
93 
95 {
96  SG_DEBUG("Entering\n")
97  cleanup();
100  SG_DEBUG("Leaving\n")
101 }
102 
103 bool CCustomKernel::dummy_init(int32_t rows, int32_t cols)
104 {
105  return init(new CDummyFeatures(rows), new CDummyFeatures(cols));
106 }
107 
108 bool CCustomKernel::init(CFeatures* l, CFeatures* r)
109 {
110  /* make it possible to call with NULL values since features are useless
111  * for custom kernel matrix */
112  if (!l)
113  l=lhs;
114 
115  if (!r)
116  r=rhs;
117 
118  /* Make sure l and r should not be NULL */
119  REQUIRE(l, "CFeatures l should not be NULL\n")
120  REQUIRE(r, "CFeatures r should not be NULL\n")
121 
122  /* Make sure l and r have the same type of CFeatures */
124  "Different FeatureClass: l is %d, r is %d\n",
127  "Different FeatureType: l is %d, r is %d\n",
129 
130  /* If l and r are the type of CIndexFeatures,
131  * the init function adds a subset to kernel matrix.
132  * Then call get_kernel_matrix will get the submatrix
133  * of the kernel matrix.
134  */
136  {
137  CIndexFeatures* l_idx = (CIndexFeatures*)l;
138  CIndexFeatures* r_idx = (CIndexFeatures*)r;
139 
142 
145 
147 
148  return true;
149  }
150 
151  /* For other types of CFeatures do the default actions below */
152  CKernel::init(l, r);
153 
155 
156  SG_DEBUG("num_vec_lhs: %d vs num_rows %d\n", l->get_num_vectors(), kmatrix.num_rows)
157  SG_DEBUG("num_vec_rhs: %d vs num_cols %d\n", r->get_num_vectors(), kmatrix.num_cols)
160  return init_normalizer();
161 }
162 
163 #ifdef HAVE_LINALG_LIB
165  index_t block_size, bool no_diag)
166 {
167  SG_DEBUG("Entering\n");
168 
170  {
171  SG_INFO("Row/col subsets initialized! Falling back to "
172  "CKernel::sum_symmetric_block (slower)!\n");
173  return CKernel::sum_symmetric_block(block_begin, block_size, no_diag);
174  }
175 
176  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
177  REQUIRE(m_is_symmetric, "The kernel matrix is not symmetric!\n")
178  REQUIRE(block_begin>=0 && block_begin<kmatrix.num_cols,
179  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
180  REQUIRE(block_begin+block_size<=kmatrix.num_cols,
181  "Invalid block size (%d) at starting index (%d, %d)! "
182  "Please use smaller blocks!", block_size, block_begin, block_begin)
183  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
184 
185  SG_DEBUG("Leaving\n");
186 
187  return sum_symmetric<Backend::EIGEN3>(block(kmatrix, block_begin,
188  block_begin, block_size, block_size), no_diag);
189 }
190 
191 float64_t CCustomKernel::sum_block(index_t block_begin_row,
192  index_t block_begin_col, index_t block_size_row,
193  index_t block_size_col, bool no_diag)
194 {
195  SG_DEBUG("Entering\n");
196 
198  {
199  SG_INFO("Row/col subsets initialized! Falling back to "
200  "CKernel::sum_block (slower)!\n");
201  return CKernel::sum_block(block_begin_row, block_begin_col,
202  block_size_row, block_size_col, no_diag);
203  }
204 
205  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
206  REQUIRE(block_begin_row>=0 && block_begin_row<kmatrix.num_rows &&
207  block_begin_col>=0 && block_begin_col<kmatrix.num_cols,
208  "Invalid block begin index (%d, %d)!\n",
209  block_begin_row, block_begin_col)
210  REQUIRE(block_begin_row+block_size_row<=kmatrix.num_rows &&
211  block_begin_col+block_size_col<=kmatrix.num_cols,
212  "Invalid block size (%d, %d) at starting index (%d, %d)! "
213  "Please use smaller blocks!", block_size_row, block_size_col,
214  block_begin_row, block_begin_col)
215  REQUIRE(block_size_row>=1 && block_size_col>=1,
216  "Invalid block size (%d, %d)!\n", block_size_row, block_size_col)
217 
218  // check if removal of diagonal is required/valid
219  if (no_diag && block_size_row!=block_size_col)
220  {
221  SG_WARNING("Not removing the main diagonal since block is not square!\n");
222  no_diag=false;
223  }
224 
225  SG_DEBUG("Leaving\n");
226 
227  return sum<Backend::EIGEN3>(block(kmatrix, block_begin_row, block_begin_col,
228  block_size_row, block_size_col), no_diag);
229 }
230 
232  block_begin, index_t block_size, bool no_diag)
233 {
234  SG_DEBUG("Entering\n");
235 
237  {
238  SG_INFO("Row/col subsets initialized! Falling back to "
239  "CKernel::row_wise_sum_symmetric_block (slower)!\n");
240  return CKernel::row_wise_sum_symmetric_block(block_begin, block_size,
241  no_diag);
242  }
243 
244  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
245  REQUIRE(m_is_symmetric, "The kernel matrix is not symmetric!\n")
246  REQUIRE(block_begin>=0 && block_begin<kmatrix.num_cols,
247  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
248  REQUIRE(block_begin+block_size<=kmatrix.num_cols,
249  "Invalid block size (%d) at starting index (%d, %d)! "
250  "Please use smaller blocks!", block_size, block_begin, block_begin)
251  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
252 
253  SGVector<float32_t> s=rowwise_sum<Backend::EIGEN3>(block(kmatrix, block_begin,
254  block_begin, block_size, block_size), no_diag);
255 
256  // casting to float64_t vector
257  SGVector<float64_t> sum(s.vlen);
258  for (index_t i=0; i<s.vlen; ++i)
259  sum[i]=s[i];
260 
261  SG_DEBUG("Leaving\n");
262 
263  return sum;
264 }
265 
267  index_t block_begin, index_t block_size, bool no_diag)
268 {
269  SG_DEBUG("Entering\n");
270 
272  {
273  SG_INFO("Row/col subsets initialized! Falling back to "
274  "CKernel::row_wise_sum_squared_sum_symmetric_block (slower)!\n");
276  block_size, no_diag);
277  }
278 
279  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
280  REQUIRE(m_is_symmetric, "The kernel matrix is not symmetric!\n")
281  REQUIRE(block_begin>=0 && block_begin<kmatrix.num_cols,
282  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
283  REQUIRE(block_begin+block_size<=kmatrix.num_cols,
284  "Invalid block size (%d) at starting index (%d, %d)! "
285  "Please use smaller blocks!", block_size, block_begin, block_begin)
286  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
287 
288  // initialize the matrix that accumulates the row/col-wise sum
289  // the first column stores the sum of kernel values
290  // the second column stores the sum of squared kernel values
291  SGMatrix<float64_t> row_sum(block_size, 2);
292 
293  SGVector<float32_t> sum=rowwise_sum<Backend::EIGEN3>(block(kmatrix,
294  block_begin, block_begin, block_size, block_size), no_diag);
295 
296  SGVector<float32_t> sq_sum=rowwise_sum<Backend::EIGEN3>(
297  elementwise_square<Backend::EIGEN3>(block(kmatrix,
298  block_begin, block_begin, block_size, block_size)), no_diag);
299 
300  for (index_t i=0; i<sum.vlen; ++i)
301  row_sum(i, 0)=sum[i];
302 
303  for (index_t i=0; i<sq_sum.vlen; ++i)
304  row_sum(i, 1)=sq_sum[i];
305 
306  SG_DEBUG("Leaving\n");
307 
308  return row_sum;
309 }
310 
312  block_begin_row, index_t block_begin_col, index_t block_size_row,
313  index_t block_size_col, bool no_diag)
314 {
315  SG_DEBUG("Entering\n");
316 
318  {
319  SG_INFO("Row/col subsets initialized! Falling back to "
320  "CKernel::row_col_wise_sum_block (slower)!\n");
321  return CKernel::row_col_wise_sum_block(block_begin_row, block_begin_col,
322  block_size_row, block_size_col, no_diag);
323  }
324 
325  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
326  REQUIRE(block_begin_row>=0 && block_begin_row<kmatrix.num_rows &&
327  block_begin_col>=0 && block_begin_col<kmatrix.num_cols,
328  "Invalid block begin index (%d, %d)!\n",
329  block_begin_row, block_begin_col)
330  REQUIRE(block_begin_row+block_size_row<=kmatrix.num_rows &&
331  block_begin_col+block_size_col<=kmatrix.num_cols,
332  "Invalid block size (%d, %d) at starting index (%d, %d)! "
333  "Please use smaller blocks!", block_size_row, block_size_col,
334  block_begin_row, block_begin_col)
335  REQUIRE(block_size_row>=1 && block_size_col>=1,
336  "Invalid block size (%d, %d)!\n", block_size_row, block_size_col)
337 
338  // check if removal of diagonal is required/valid
339  if (no_diag && block_size_row!=block_size_col)
340  {
341  SG_WARNING("Not removing the main diagonal since block is not square!\n");
342  no_diag=false;
343  }
344 
345  // initialize the vector that accumulates the row/col-wise sum
346  // the first block_size_row entries store the row-wise sum of kernel values
347  // the nextt block_size_col entries store the col-wise sum of kernel values
348  SGVector<float64_t> sum(block_size_row+block_size_col);
349 
350  SGVector<float32_t> rowwise=rowwise_sum<Backend::EIGEN3>(block(kmatrix,
351  block_begin_row, block_begin_col, block_size_row,
352  block_size_col), no_diag);
353 
354  SGVector<float32_t> colwise=colwise_sum<Backend::EIGEN3>(block(kmatrix,
355  block_begin_row, block_begin_col, block_size_row,
356  block_size_col), no_diag);
357 
358  for (index_t i=0; i<rowwise.vlen; ++i)
359  sum[i]=rowwise[i];
360 
361  for (index_t i=0; i<colwise.vlen; ++i)
362  sum[i+rowwise.vlen]=colwise[i];
363 
364  SG_DEBUG("Leaving\n");
365 
366  return sum;
367 }
368 #endif // HAVE_LINALG_LIB
369 
371 {
372  SG_DEBUG("Entering\n")
375 
376  kmatrix=SGMatrix<float32_t>();
377  upper_diagonal=false;
378 
379  SG_DEBUG("Leaving\n")
380 }
381 
383 {
384  cleanup_custom();
386 }
387 
389 {
392 }
393 
395 {
398 }
399 
401 {
404 }
405 
407 {
410 }
411 
413 {
416  else
417  num_lhs=kmatrix.num_rows;
418 }
419 
421 {
424 }
425 
427 {
430 }
431 
433 {
436 }
437 
439 {
442 }
443 
445 {
448  else
449  num_rhs=kmatrix.num_cols;
450 }
#define SG_INFO(...)
Definition: SGIO.h:118
virtual void cleanup()
Definition: Kernel.cpp:173
int32_t index_t
Definition: common.h:62
virtual void add_row_subset(SGVector< index_t > subset)
SGMatrix< float32_t > kmatrix
Definition: CustomKernel.h:606
int32_t num_rhs
number of feature vectors on right hand side
Definition: Kernel.h:1070
index_t get_size() const
Definition: SubsetStack.h:80
The Custom Kernel allows for custom user provided kernel matrices.
Definition: CustomKernel.h:36
The class IndexFeatures implements features that contain the index of the features. This features used in the CCustomKernel::init to make the subset of the kernel matrix. Initial CIndexFeature of row_idx and col_idx, pass them to the CCustomKernel::init(row_idx, col_idx), then use CCustomKernel::get_kernel_matrix() will get the sub kernel matrix specified by the row_idx and col_idx.
Definition: IndexFeatures.h:53
SGMatrix< float32_t > get_float32_kernel_matrix()
Definition: CustomKernel.h:551
virtual float64_t sum_block(index_t block_begin_row, index_t block_begin_col, index_t block_size_row, index_t block_size_col, bool no_diag=false)
Definition: Kernel.cpp:1080
bool get_lhs_equals_rhs()
Definition: Kernel.h:544
CSubsetStack * m_col_subset_stack
Definition: CustomKernel.h:618
virtual int32_t get_num_vectors() const =0
#define REQUIRE(x,...)
Definition: SGIO.h:206
index_t num_cols
Definition: SGMatrix.h:376
float64_t kernel(int32_t idx_a, int32_t idx_b)
Definition: Kernel.h:207
virtual void cleanup()
virtual void remove_all_row_subsets()
SGMatrix< float64_t > get_kernel_matrix()
Definition: Kernel.h:220
#define SG_REF(x)
Definition: SGObject.h:54
index_t num_rows
Definition: SGMatrix.h:374
class to add subset support to another class. A CSubsetStackStack instance should be added and wrappe...
Definition: SubsetStack.h:37
virtual SGMatrix< float64_t > row_wise_sum_squared_sum_symmetric_block(index_t block_begin, index_t block_size, bool no_diag=true)
Definition: Kernel.cpp:1180
virtual void remove_col_subset()
SGVector< index_t > get_feature_index()
virtual void remove_row_subset()
virtual void add_col_subset(SGVector< index_t > subset)
index_t vlen
Definition: SGVector.h:494
virtual void add_subset(SGVector< index_t > subset)
Definition: SubsetStack.cpp:80
#define ASSERT(x)
Definition: SGIO.h:201
Class SGObject is the base class of all shogun objects.
Definition: SGObject.h:115
virtual void row_subset_changed_post()
virtual void remove_all_subsets()
Definition: SubsetStack.cpp:59
virtual SGVector< float64_t > row_col_wise_sum_block(index_t block_begin_row, index_t block_begin_col, index_t block_size_row, index_t block_size_col, bool no_diag=false)
Definition: Kernel.cpp:1239
virtual void add_subset_in_place(SGVector< index_t > subset)
virtual float64_t sum_symmetric_block(index_t block_begin, index_t block_size, bool no_diag=true)
Definition: Kernel.cpp:1027
double float64_t
Definition: common.h:50
bool set_full_kernel_matrix_from_full(SGMatrix< float32_t > full_kernel_matrix, bool check_symmetry=false)
Definition: CustomKernel.h:263
virtual SGVector< float64_t > row_wise_sum_symmetric_block(index_t block_begin, index_t block_size, bool no_diag=true)
Definition: Kernel.cpp:1126
virtual EFeatureClass get_feature_class() const =0
int32_t num_lhs
number of feature vectors on left hand side
Definition: Kernel.h:1068
virtual bool dummy_init(int32_t rows, int32_t cols)
virtual void remove_all_col_subsets()
virtual bool init_normalizer()
Definition: Kernel.cpp:168
float float32_t
Definition: common.h:49
CFeatures * rhs
feature vectors to occur on right hand side
Definition: Kernel.h:1062
The class DummyFeatures implements features that only know the number of feature objects (but don't a...
Definition: DummyFeatures.h:25
#define SG_UNREF(x)
Definition: SGObject.h:55
#define SG_DEBUG(...)
Definition: SGIO.h:107
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
bool lhs_equals_rhs
lhs
Definition: Kernel.h:1065
virtual EKernelType get_kernel_type()=0
CFeatures * lhs
feature vectors to occur on left hand side
Definition: Kernel.h:1060
The class Features is the base class of all feature objects.
Definition: Features.h:68
virtual void col_subset_changed_post()
virtual bool has_subsets() const
Definition: SubsetStack.h:89
The Kernel base class.
Definition: Kernel.h:159
virtual void remove_subset()
virtual void add_col_subset_in_place(SGVector< index_t > subset)
#define SG_WARNING(...)
Definition: SGIO.h:128
#define SG_ADD(...)
Definition: SGObject.h:84
CSubsetStack * m_row_subset_stack
Definition: CustomKernel.h:615
virtual void add_row_subset_in_place(SGVector< index_t > subset)
virtual EFeatureType get_feature_type() const =0
Block< Matrix > block(Matrix matrix, index_t row_begin, index_t col_begin, index_t row_size, index_t col_size)
Definition: Block.h:102

SHOGUN Machine Learning Toolbox - Documentation