SHOGUN  6.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
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>
19 
20 using namespace shogun;
21 using namespace linalg;
22 
23 void CCustomKernel::init()
24 {
25  m_row_subset_stack=new CSubsetStack();
26  SG_REF(m_row_subset_stack)
27  m_col_subset_stack=new CSubsetStack();
28  SG_REF(m_col_subset_stack)
29  m_is_symmetric=false;
30  m_free_km=true;
31 
32  SG_ADD((CSGObject**)&m_row_subset_stack, "row_subset_stack",
33  "Subset stack of rows", MS_NOT_AVAILABLE);
34  SG_ADD((CSGObject**)&m_col_subset_stack, "col_subset_stack",
35  "Subset stack of columns", MS_NOT_AVAILABLE);
36  SG_ADD(&m_free_km, "free_km", "Whether kernel matrix should be freed in "
37  "destructor", MS_NOT_AVAILABLE);
38  SG_ADD(&m_is_symmetric, "is_symmetric", "Whether kernel matrix is symmetric",
39  MS_NOT_AVAILABLE);
40  SG_ADD(&kmatrix, "kmatrix", "Kernel matrix.", MS_NOT_AVAILABLE);
41  SG_ADD(&upper_diagonal, "upper_diagonal", "Upper diagonal", MS_NOT_AVAILABLE);
42 }
43 
45 : CKernel(10), kmatrix(), upper_diagonal(false)
46 {
47  SG_DEBUG("created CCustomKernel\n")
48  init();
49 }
50 
52 : CKernel(10)
53 {
54  SG_DEBUG("created CCustomKernel\n")
55  init();
56 
57  /* if constructed from a custom kernel, use same kernel matrix */
58  if (k->get_kernel_type()==K_CUSTOM)
59  {
60  CCustomKernel* casted=(CCustomKernel*)k;
63  m_free_km=false;
64  }
65  else
66  {
69  }
70 }
71 
73 : CKernel(10), upper_diagonal(false)
74 {
75  SG_DEBUG("Entering\n")
76  init();
78  SG_DEBUG("Leaving\n")
79 }
80 
82 : CKernel(10), upper_diagonal(false)
83 {
84  SG_DEBUG("Entering\n")
85  init();
87  SG_DEBUG("Leaving\n")
88 }
89 
91 {
92  SG_DEBUG("Entering\n")
93  cleanup();
96  SG_DEBUG("Leaving\n")
97 }
98 
99 bool CCustomKernel::dummy_init(int32_t rows, int32_t cols)
100 {
101  return init(new CDummyFeatures(rows), new CDummyFeatures(cols));
102 }
103 
104 bool CCustomKernel::init(CFeatures* l, CFeatures* r)
105 {
106  /* make it possible to call with NULL values since features are useless
107  * for custom kernel matrix */
108  if (!l)
109  l=lhs;
110 
111  if (!r)
112  r=rhs;
113 
114  /* Make sure l and r should not be NULL */
115  REQUIRE(l, "CFeatures l should not be NULL\n")
116  REQUIRE(r, "CFeatures r should not be NULL\n")
117 
118  /* Make sure l and r have the same type of CFeatures */
120  "Different FeatureClass: l is %d, r is %d\n",
123  "Different FeatureType: l is %d, r is %d\n",
125 
126  /* If l and r are the type of CIndexFeatures,
127  * the init function adds a subset to kernel matrix.
128  * Then call get_kernel_matrix will get the submatrix
129  * of the kernel matrix.
130  */
132  {
133  CIndexFeatures* l_idx = (CIndexFeatures*)l;
134  CIndexFeatures* r_idx = (CIndexFeatures*)r;
135 
138 
141 
143 
144  return true;
145  }
146 
147  /* For other types of CFeatures do the default actions below */
148  CKernel::init(l, r);
149 
151 
152  SG_DEBUG("num_vec_lhs: %d vs num_rows %d\n", l->get_num_vectors(), kmatrix.num_rows)
153  SG_DEBUG("num_vec_rhs: %d vs num_cols %d\n", r->get_num_vectors(), kmatrix.num_cols)
156  return init_normalizer();
157 }
158 
160  index_t block_size, bool no_diag)
161 {
162  SG_DEBUG("Entering\n");
163 
165  {
166  SG_INFO("Row/col subsets initialized! Falling back to "
167  "CKernel::sum_symmetric_block (slower)!\n");
168  return CKernel::sum_symmetric_block(block_begin, block_size, no_diag);
169  }
170 
171  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
172  REQUIRE(m_is_symmetric, "The kernel matrix is not symmetric!\n")
173  REQUIRE(block_begin>=0 && block_begin<kmatrix.num_cols,
174  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
175  REQUIRE(block_begin+block_size<=kmatrix.num_cols,
176  "Invalid block size (%d) at starting index (%d, %d)! "
177  "Please use smaller blocks!", block_size, block_begin, block_begin)
178  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
179 
180  SG_DEBUG("Leaving\n");
181 
182  return sum_symmetric(block(kmatrix, block_begin,
183  block_begin, block_size, block_size), no_diag);
184 }
185 
187  index_t block_begin_col, index_t block_size_row,
188  index_t block_size_col, bool no_diag)
189 {
190  SG_DEBUG("Entering\n");
191 
193  {
194  SG_INFO("Row/col subsets initialized! Falling back to "
195  "CKernel::sum_block (slower)!\n");
196  return CKernel::sum_block(block_begin_row, block_begin_col,
197  block_size_row, block_size_col, no_diag);
198  }
199 
200  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
201  REQUIRE(block_begin_row>=0 && block_begin_row<kmatrix.num_rows &&
202  block_begin_col>=0 && block_begin_col<kmatrix.num_cols,
203  "Invalid block begin index (%d, %d)!\n",
204  block_begin_row, block_begin_col)
205  REQUIRE(block_begin_row+block_size_row<=kmatrix.num_rows &&
206  block_begin_col+block_size_col<=kmatrix.num_cols,
207  "Invalid block size (%d, %d) at starting index (%d, %d)! "
208  "Please use smaller blocks!", block_size_row, block_size_col,
209  block_begin_row, block_begin_col)
210  REQUIRE(block_size_row>=1 && block_size_col>=1,
211  "Invalid block size (%d, %d)!\n", block_size_row, block_size_col)
212 
213  // check if removal of diagonal is required/valid
214  if (no_diag && block_size_row!=block_size_col)
215  {
216  SG_WARNING("Not removing the main diagonal since block is not square!\n");
217  no_diag=false;
218  }
219 
220  SG_DEBUG("Leaving\n");
221 
222  return sum(block(kmatrix, block_begin_row, block_begin_col,
223  block_size_row, block_size_col), no_diag);
224 }
225 
227  block_begin, index_t block_size, bool no_diag)
228 {
229  SG_DEBUG("Entering\n");
230 
232  {
233  SG_INFO("Row/col subsets initialized! Falling back to "
234  "CKernel::row_wise_sum_symmetric_block (slower)!\n");
235  return CKernel::row_wise_sum_symmetric_block(block_begin, block_size,
236  no_diag);
237  }
238 
239  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
240  REQUIRE(m_is_symmetric, "The kernel matrix is not symmetric!\n")
241  REQUIRE(block_begin>=0 && block_begin<kmatrix.num_cols,
242  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
243  REQUIRE(block_begin+block_size<=kmatrix.num_cols,
244  "Invalid block size (%d) at starting index (%d, %d)! "
245  "Please use smaller blocks!", block_size, block_begin, block_begin)
246  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
247 
249  block_begin, block_size, block_size), no_diag);
250 
251  // casting to float64_t vector
253  for (index_t i=0; i<s.vlen; ++i)
254  sum[i]=s[i];
255 
256  SG_DEBUG("Leaving\n");
257 
258  return sum;
259 }
260 
262  index_t block_begin, index_t block_size, bool no_diag)
263 {
264  SG_DEBUG("Entering\n");
265 
267  {
268  SG_INFO("Row/col subsets initialized! Falling back to "
269  "CKernel::row_wise_sum_squared_sum_symmetric_block (slower)!\n");
271  block_size, no_diag);
272  }
273 
274  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
275  REQUIRE(m_is_symmetric, "The kernel matrix is not symmetric!\n")
276  REQUIRE(block_begin>=0 && block_begin<kmatrix.num_cols,
277  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
278  REQUIRE(block_begin+block_size<=kmatrix.num_cols,
279  "Invalid block size (%d) at starting index (%d, %d)! "
280  "Please use smaller blocks!", block_size, block_begin, block_begin)
281  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
282 
283  // initialize the matrix that accumulates the row/col-wise sum
284  // the first column stores the sum of kernel values
285  // the second column stores the sum of squared kernel values
286  SGMatrix<float64_t> row_sum(block_size, 2);
287 
289  block_begin, block_begin, block_size, block_size), no_diag);
290 
291  auto kmatrix_block = block(kmatrix, block_begin, block_begin, block_size, block_size);
293  element_prod(kmatrix_block, kmatrix_block), no_diag);
294 
295  for (index_t i=0; i<sum.vlen; ++i)
296  row_sum(i, 0)=sum[i];
297 
298  for (index_t i=0; i<sq_sum.vlen; ++i)
299  row_sum(i, 1)=sq_sum[i];
300 
301  SG_DEBUG("Leaving\n");
302 
303  return row_sum;
304 }
305 
307  block_begin_row, index_t block_begin_col, index_t block_size_row,
308  index_t block_size_col, bool no_diag)
309 {
310  SG_DEBUG("Entering\n");
311 
313  {
314  SG_INFO("Row/col subsets initialized! Falling back to "
315  "CKernel::row_col_wise_sum_block (slower)!\n");
316  return CKernel::row_col_wise_sum_block(block_begin_row, block_begin_col,
317  block_size_row, block_size_col, no_diag);
318  }
319 
320  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
321  REQUIRE(block_begin_row>=0 && block_begin_row<kmatrix.num_rows &&
322  block_begin_col>=0 && block_begin_col<kmatrix.num_cols,
323  "Invalid block begin index (%d, %d)!\n",
324  block_begin_row, block_begin_col)
325  REQUIRE(block_begin_row+block_size_row<=kmatrix.num_rows &&
326  block_begin_col+block_size_col<=kmatrix.num_cols,
327  "Invalid block size (%d, %d) at starting index (%d, %d)! "
328  "Please use smaller blocks!", block_size_row, block_size_col,
329  block_begin_row, block_begin_col)
330  REQUIRE(block_size_row>=1 && block_size_col>=1,
331  "Invalid block size (%d, %d)!\n", block_size_row, block_size_col)
332 
333  // check if removal of diagonal is required/valid
334  if (no_diag && block_size_row!=block_size_col)
335  {
336  SG_WARNING("Not removing the main diagonal since block is not square!\n");
337  no_diag=false;
338  }
339 
340  // initialize the vector that accumulates the row/col-wise sum
341  // the first block_size_row entries store the row-wise sum of kernel values
342  // the nextt block_size_col entries store the col-wise sum of kernel values
343  SGVector<float64_t> sum(block_size_row+block_size_col);
344 
346  block_begin_row, block_begin_col, block_size_row,
347  block_size_col), no_diag);
348 
350  block_begin_row, block_begin_col, block_size_row,
351  block_size_col), no_diag);
352 
353  for (index_t i=0; i<rowwise.vlen; ++i)
354  sum[i]=rowwise[i];
355 
356  for (index_t i=0; i<colwise.vlen; ++i)
357  sum[i+rowwise.vlen]=colwise[i];
358 
359  SG_DEBUG("Leaving\n");
360 
361  return sum;
362 }
363 
365 {
366  SG_DEBUG("Entering\n")
369 
371  upper_diagonal=false;
372 
373  SG_DEBUG("Leaving\n")
374 }
375 
377 {
378  cleanup_custom();
380 }
381 
383 {
386 }
387 
389 {
392 }
393 
395 {
398 }
399 
401 {
404 }
405 
407 {
410  else
412 }
413 
415 {
418 }
419 
421 {
424 }
425 
427 {
430 }
431 
433 {
436 }
437 
439 {
442  else
444 }
T sum_symmetric(const SGMatrix< T > &a, bool no_diag=false)
#define SG_INFO(...)
Definition: SGIO.h:117
virtual void cleanup()
Definition: Kernel.cpp:171
int32_t index_t
Definition: common.h:72
virtual void add_row_subset(SGVector< index_t > subset)
SGMatrix< float32_t > kmatrix
Definition: CustomKernel.h:603
int32_t num_rhs
number of feature vectors on right hand side
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
virtual SGMatrix< float64_t > row_wise_sum_squared_sum_symmetric_block(index_t block_begin, index_t block_size, bool no_diag=true)
SGMatrix< float32_t > get_float32_kernel_matrix()
Definition: CustomKernel.h:548
virtual SGVector< float64_t > row_wise_sum_symmetric_block(index_t block_begin, index_t block_size, bool no_diag=true)
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:1053
bool get_lhs_equals_rhs()
SGVector< T > rowwise_sum(const SGMatrix< T > &mat, bool no_diag=false)
CSubsetStack * m_col_subset_stack
Definition: CustomKernel.h:615
virtual int32_t get_num_vectors() const =0
#define REQUIRE(x,...)
Definition: SGIO.h:205
index_t num_cols
Definition: SGMatrix.h:465
virtual void cleanup()
virtual float64_t sum_symmetric_block(index_t block_begin, index_t block_size, bool no_diag=true)
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)
virtual void remove_all_row_subsets()
SGMatrix< float64_t > get_kernel_matrix()
#define SG_REF(x)
Definition: SGObject.h:52
index_t num_rows
Definition: SGMatrix.h:463
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:1152
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)
SGVector< T > colwise_sum(const SGMatrix< T > &mat, bool no_diag=false)
index_t vlen
Definition: SGVector.h:545
virtual void add_subset(SGVector< index_t > subset)
Definition: SubsetStack.cpp:80
#define ASSERT(x)
Definition: SGIO.h:200
Class SGObject is the base class of all shogun objects.
Definition: SGObject.h:125
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:1211
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:1002
double float64_t
Definition: common.h:60
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:1098
virtual EFeatureClass get_feature_class() const =0
int32_t num_lhs
number of feature vectors on left hand side
virtual bool dummy_init(int32_t rows, int32_t cols)
virtual void remove_all_col_subsets()
virtual bool init_normalizer()
Definition: Kernel.cpp:166
CFeatures * rhs
feature vectors to occur on right hand side
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:53
#define SG_DEBUG(...)
Definition: SGIO.h:106
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
T sum(const Container< T > &a, bool no_diag=false)
bool lhs_equals_rhs
lhs
virtual EKernelType get_kernel_type()=0
CFeatures * lhs
feature vectors to occur on left hand side
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)
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.
virtual void remove_subset()
virtual void add_col_subset_in_place(SGVector< index_t > subset)
#define SG_WARNING(...)
Definition: SGIO.h:127
#define SG_ADD(...)
Definition: SGObject.h:94
CSubsetStack * m_row_subset_stack
Definition: CustomKernel.h:612
void element_prod(Block< SGMatrix< T >> &a, Block< SGMatrix< T >> &b, SGMatrix< T > &result)
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)

SHOGUN Machine Learning Toolbox - Documentation