SHOGUN  4.1.0
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
CustomKernel.cpp
浏览该文件的文档.
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
164 #ifdef HAVE_EIGEN3
166  index_t block_size, bool no_diag)
167 {
168  SG_DEBUG("Entering\n");
169 
171  {
172  SG_INFO("Row/col subsets initialized! Falling back to "
173  "CKernel::sum_symmetric_block (slower)!\n");
174  return CKernel::sum_symmetric_block(block_begin, block_size, no_diag);
175  }
176 
177  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
178  REQUIRE(m_is_symmetric, "The kernel matrix is not symmetric!\n")
179  REQUIRE(block_begin>=0 && block_begin<kmatrix.num_cols,
180  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
181  REQUIRE(block_begin+block_size<=kmatrix.num_cols,
182  "Invalid block size (%d) at starting index (%d, %d)! "
183  "Please use smaller blocks!", block_size, block_begin, block_begin)
184  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
185 
186  SG_DEBUG("Leaving\n");
187 
188  return sum_symmetric<Backend::EIGEN3>(block(kmatrix, block_begin,
189  block_begin, block_size, block_size), no_diag);
190 }
191 
192 float64_t CCustomKernel::sum_block(index_t block_begin_row,
193  index_t block_begin_col, index_t block_size_row,
194  index_t block_size_col, bool no_diag)
195 {
196  SG_DEBUG("Entering\n");
197 
199  {
200  SG_INFO("Row/col subsets initialized! Falling back to "
201  "CKernel::sum_block (slower)!\n");
202  return CKernel::sum_block(block_begin_row, block_begin_col,
203  block_size_row, block_size_col, no_diag);
204  }
205 
206  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
207  REQUIRE(block_begin_row>=0 && block_begin_row<kmatrix.num_rows &&
208  block_begin_col>=0 && block_begin_col<kmatrix.num_cols,
209  "Invalid block begin index (%d, %d)!\n",
210  block_begin_row, block_begin_col)
211  REQUIRE(block_begin_row+block_size_row<=kmatrix.num_rows &&
212  block_begin_col+block_size_col<=kmatrix.num_cols,
213  "Invalid block size (%d, %d) at starting index (%d, %d)! "
214  "Please use smaller blocks!", block_size_row, block_size_col,
215  block_begin_row, block_begin_col)
216  REQUIRE(block_size_row>=1 && block_size_col>=1,
217  "Invalid block size (%d, %d)!\n", block_size_row, block_size_col)
218 
219  // check if removal of diagonal is required/valid
220  if (no_diag && block_size_row!=block_size_col)
221  {
222  SG_WARNING("Not removing the main diagonal since block is not square!\n");
223  no_diag=false;
224  }
225 
226  SG_DEBUG("Leaving\n");
227 
228  return sum<Backend::EIGEN3>(block(kmatrix, block_begin_row, block_begin_col,
229  block_size_row, block_size_col), no_diag);
230 }
231 
233  block_begin, index_t block_size, bool no_diag)
234 {
235  SG_DEBUG("Entering\n");
236 
238  {
239  SG_INFO("Row/col subsets initialized! Falling back to "
240  "CKernel::row_wise_sum_symmetric_block (slower)!\n");
241  return CKernel::row_wise_sum_symmetric_block(block_begin, block_size,
242  no_diag);
243  }
244 
245  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
246  REQUIRE(m_is_symmetric, "The kernel matrix is not symmetric!\n")
247  REQUIRE(block_begin>=0 && block_begin<kmatrix.num_cols,
248  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
249  REQUIRE(block_begin+block_size<=kmatrix.num_cols,
250  "Invalid block size (%d) at starting index (%d, %d)! "
251  "Please use smaller blocks!", block_size, block_begin, block_begin)
252  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
253 
254  SGVector<float32_t> s=rowwise_sum<Backend::EIGEN3>(block(kmatrix, block_begin,
255  block_begin, block_size, block_size), no_diag);
256 
257  // casting to float64_t vector
258  SGVector<float64_t> sum(s.vlen);
259  for (index_t i=0; i<s.vlen; ++i)
260  sum[i]=s[i];
261 
262  SG_DEBUG("Leaving\n");
263 
264  return sum;
265 }
266 
268  index_t block_begin, index_t block_size, bool no_diag)
269 {
270  SG_DEBUG("Entering\n");
271 
273  {
274  SG_INFO("Row/col subsets initialized! Falling back to "
275  "CKernel::row_wise_sum_squared_sum_symmetric_block (slower)!\n");
277  block_size, no_diag);
278  }
279 
280  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
281  REQUIRE(m_is_symmetric, "The kernel matrix is not symmetric!\n")
282  REQUIRE(block_begin>=0 && block_begin<kmatrix.num_cols,
283  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
284  REQUIRE(block_begin+block_size<=kmatrix.num_cols,
285  "Invalid block size (%d) at starting index (%d, %d)! "
286  "Please use smaller blocks!", block_size, block_begin, block_begin)
287  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
288 
289  // initialize the matrix that accumulates the row/col-wise sum
290  // the first column stores the sum of kernel values
291  // the second column stores the sum of squared kernel values
292  SGMatrix<float64_t> row_sum(block_size, 2);
293 
294  SGVector<float32_t> sum=rowwise_sum<Backend::EIGEN3>(block(kmatrix,
295  block_begin, block_begin, block_size, block_size), no_diag);
296 
297  SGVector<float32_t> sq_sum=rowwise_sum<Backend::EIGEN3>(
298  elementwise_square<Backend::EIGEN3>(block(kmatrix,
299  block_begin, block_begin, block_size, block_size)), no_diag);
300 
301  for (index_t i=0; i<sum.vlen; ++i)
302  row_sum(i, 0)=sum[i];
303 
304  for (index_t i=0; i<sq_sum.vlen; ++i)
305  row_sum(i, 1)=sq_sum[i];
306 
307  SG_DEBUG("Leaving\n");
308 
309  return row_sum;
310 }
311 
313  block_begin_row, index_t block_begin_col, index_t block_size_row,
314  index_t block_size_col, bool no_diag)
315 {
316  SG_DEBUG("Entering\n");
317 
319  {
320  SG_INFO("Row/col subsets initialized! Falling back to "
321  "CKernel::row_col_wise_sum_block (slower)!\n");
322  return CKernel::row_col_wise_sum_block(block_begin_row, block_begin_col,
323  block_size_row, block_size_col, no_diag);
324  }
325 
326  REQUIRE(kmatrix.matrix, "The kernel matrix is not initialized!\n")
327  REQUIRE(block_begin_row>=0 && block_begin_row<kmatrix.num_rows &&
328  block_begin_col>=0 && block_begin_col<kmatrix.num_cols,
329  "Invalid block begin index (%d, %d)!\n",
330  block_begin_row, block_begin_col)
331  REQUIRE(block_begin_row+block_size_row<=kmatrix.num_rows &&
332  block_begin_col+block_size_col<=kmatrix.num_cols,
333  "Invalid block size (%d, %d) at starting index (%d, %d)! "
334  "Please use smaller blocks!", block_size_row, block_size_col,
335  block_begin_row, block_begin_col)
336  REQUIRE(block_size_row>=1 && block_size_col>=1,
337  "Invalid block size (%d, %d)!\n", block_size_row, block_size_col)
338 
339  // check if removal of diagonal is required/valid
340  if (no_diag && block_size_row!=block_size_col)
341  {
342  SG_WARNING("Not removing the main diagonal since block is not square!\n");
343  no_diag=false;
344  }
345 
346  // initialize the vector that accumulates the row/col-wise sum
347  // the first block_size_row entries store the row-wise sum of kernel values
348  // the nextt block_size_col entries store the col-wise sum of kernel values
349  SGVector<float64_t> sum(block_size_row+block_size_col);
350 
351  SGVector<float32_t> rowwise=rowwise_sum<Backend::EIGEN3>(block(kmatrix,
352  block_begin_row, block_begin_col, block_size_row,
353  block_size_col), no_diag);
354 
355  SGVector<float32_t> colwise=colwise_sum<Backend::EIGEN3>(block(kmatrix,
356  block_begin_row, block_begin_col, block_size_row,
357  block_size_col), no_diag);
358 
359  for (index_t i=0; i<rowwise.vlen; ++i)
360  sum[i]=rowwise[i];
361 
362  for (index_t i=0; i<colwise.vlen; ++i)
363  sum[i+rowwise.vlen]=colwise[i];
364 
365  SG_DEBUG("Leaving\n");
366 
367  return sum;
368 }
369 #endif // HAVE_EIGEN3
370 #endif // HAVE_LINALG_LIB
371 
373 {
374  SG_DEBUG("Entering\n")
377 
378  kmatrix=SGMatrix<float32_t>();
379  upper_diagonal=false;
380 
381  SG_DEBUG("Leaving\n")
382 }
383 
385 {
386  cleanup_custom();
388 }
389 
391 {
394 }
395 
397 {
400 }
401 
403 {
406 }
407 
409 {
412 }
413 
415 {
418  else
419  num_lhs=kmatrix.num_rows;
420 }
421 
423 {
426 }
427 
429 {
432 }
433 
435 {
438 }
439 
441 {
444 }
445 
447 {
450  else
451  num_rhs=kmatrix.num_cols;
452 }
#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:608
int32_t num_rhs
number of feature vectors on right hand side
Definition: Kernel.h:1069
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:553
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:1079
bool get_lhs_equals_rhs()
Definition: Kernel.h:543
CSubsetStack * m_col_subset_stack
Definition: CustomKernel.h:620
virtual int32_t get_num_vectors() const =0
#define REQUIRE(x,...)
Definition: SGIO.h:206
index_t num_cols
Definition: SGMatrix.h:378
float64_t kernel(int32_t idx_a, int32_t idx_b)
Definition: Kernel.h:206
virtual void cleanup()
virtual void remove_all_row_subsets()
SGMatrix< float64_t > get_kernel_matrix()
Definition: Kernel.h:219
#define SG_REF(x)
Definition: SGObject.h:51
index_t num_rows
Definition: SGMatrix.h:376
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:1179
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:112
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:1238
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:1026
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:1125
virtual EFeatureClass get_feature_class() const =0
int32_t num_lhs
number of feature vectors on left hand side
Definition: Kernel.h:1067
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:1061
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:52
#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:1064
virtual EKernelType get_kernel_type()=0
CFeatures * lhs
feature vectors to occur on left hand side
Definition: Kernel.h:1059
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:158
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:81
CSubsetStack * m_row_subset_stack
Definition: CustomKernel.h:617
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 机器学习工具包 - 项目文档