SHOGUN v0.9.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 1999-2009 Soeren Sonnenburg 00008 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00009 */ 00010 00011 #ifndef _CUSTOMKERNEL_H___ 00012 #define _CUSTOMKERNEL_H___ 00013 00014 #include "lib/Mathematics.h" 00015 #include "lib/common.h" 00016 #include "kernel/Kernel.h" 00017 #include "features/Features.h" 00018 00019 namespace shogun 00020 { 00029 class CCustomKernel: public CKernel 00030 { 00031 void init(void); 00032 00033 public: 00035 CCustomKernel(); 00036 00042 CCustomKernel(CKernel* k); 00043 00054 CCustomKernel( 00055 const float64_t* km, int32_t rows, int32_t cols); 00056 00067 CCustomKernel( 00068 const float32_t* km, int32_t rows, int32_t cols); 00069 00070 virtual ~CCustomKernel(); 00071 00082 virtual bool dummy_init(int32_t rows, int32_t cols); 00083 00090 virtual bool init(CFeatures* l, CFeatures* r); 00091 00093 virtual void cleanup(); 00094 00099 inline virtual EKernelType get_kernel_type() { return K_CUSTOM; } 00100 00105 inline virtual EFeatureType get_feature_type() { return F_ANY; } 00106 00111 inline virtual EFeatureClass get_feature_class() { return C_ANY; } 00112 00117 virtual const char* get_name() const { return "CustomKernel"; } 00118 00129 bool set_triangle_kernel_matrix_from_triangle( 00130 const float64_t* km, int32_t len) 00131 { 00132 return set_triangle_kernel_matrix_from_triangle_generic(km, len); 00133 } 00134 00145 bool set_triangle_kernel_matrix_from_triangle( 00146 const float32_t* km, int32_t len) 00147 { 00148 return set_triangle_kernel_matrix_from_triangle_generic(km, len); 00149 } 00150 00161 template <class T> 00162 bool set_triangle_kernel_matrix_from_triangle_generic( 00163 const T* km, int64_t len) 00164 { 00165 ASSERT(km); 00166 ASSERT(len>0); 00167 00168 int64_t cols = (int64_t) floor(-0.5 + CMath::sqrt(0.25+2*len)); 00169 00170 int64_t int32_max=2147483647; 00171 00172 if (cols> int32_max) 00173 SG_ERROR("Matrix larger than %d x %d\n", int32_max); 00174 00175 if (cols*(cols+1)/2 != len) 00176 { 00177 SG_ERROR("km should be a vector containing a lower triangle matrix, with len=cols*(cols+1)/2 elements\n"); 00178 return false; 00179 } 00180 00181 cleanup_custom(); 00182 SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols); 00183 00184 kmatrix= new float32_t[len]; 00185 00186 upper_diagonal=true; 00187 num_rows=cols; 00188 num_cols=cols; 00189 00190 for (int64_t i=0; i<len; i++) 00191 kmatrix[i]=km[i]; 00192 00193 dummy_init(num_rows, num_cols); 00194 return true; 00195 } 00196 00207 inline bool set_triangle_kernel_matrix_from_full( 00208 const float64_t* km, int32_t rows, int32_t cols) 00209 { 00210 return set_triangle_kernel_matrix_from_full_generic(km, rows, cols); 00211 } 00212 00223 inline bool set_triangle_kernel_matrix_from_full( 00224 const float32_t* km, int32_t rows, int32_t cols) 00225 { 00226 return set_triangle_kernel_matrix_from_full_generic(km, rows, cols); 00227 } 00228 00237 template <class T> 00238 bool set_triangle_kernel_matrix_from_full_generic( 00239 const T* km, int32_t rows, int32_t cols) 00240 { 00241 ASSERT(rows==cols); 00242 00243 cleanup_custom(); 00244 SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols); 00245 00246 kmatrix= new float32_t[(int64_t(cols)+1)*cols/2]; 00247 00248 upper_diagonal=true; 00249 num_rows=cols; 00250 num_cols=cols; 00251 00252 for (int64_t row=0; row<num_rows; row++) 00253 { 00254 for (int64_t col=row; col<num_cols; col++) 00255 { 00256 int64_t idx=row * num_cols - row*(row+1)/2 + col; 00257 kmatrix[idx]= (float32_t) km[col*num_rows+row]; 00258 } 00259 } 00260 dummy_init(rows, cols); 00261 return true; 00262 } 00263 00273 bool set_full_kernel_matrix_from_full( 00274 const float64_t* km, int32_t rows, int32_t cols) 00275 { 00276 return set_full_kernel_matrix_from_full_generic(km, rows, cols); 00277 } 00278 00288 bool set_full_kernel_matrix_from_full( 00289 const float32_t* km, int32_t rows, int32_t cols) 00290 { 00291 return set_full_kernel_matrix_from_full_generic(km, rows, cols); 00292 } 00293 00301 template <class T> 00302 bool set_full_kernel_matrix_from_full_generic( 00303 const T* km, int32_t rows, int32_t cols) 00304 { 00305 cleanup_custom(); 00306 SG_DEBUG( "using custom kernel of size %dx%d\n", rows,cols); 00307 00308 kmatrix= new float32_t[int64_t(rows)*cols]; 00309 00310 upper_diagonal=false; 00311 num_rows=rows; 00312 num_cols=cols; 00313 00314 for (int32_t row=0; row<num_rows; row++) 00315 { 00316 for (int32_t col=0; col<num_cols; col++) 00317 { 00318 kmatrix[int64_t(row) * num_cols + col]=km[int64_t(col)*num_rows+row]; 00319 } 00320 } 00321 00322 dummy_init(rows, cols); 00323 return true; 00324 } 00325 00330 virtual inline int32_t get_num_vec_lhs() 00331 { 00332 return num_rows; 00333 } 00334 00339 virtual inline int32_t get_num_vec_rhs() 00340 { 00341 return num_cols; 00342 } 00343 00348 virtual inline bool has_features() 00349 { 00350 return (num_rows>0) && (num_cols>0); 00351 } 00352 00353 protected: 00360 inline virtual float64_t compute(int32_t row, int32_t col) 00361 { 00362 ASSERT(kmatrix); 00363 00364 if (upper_diagonal) 00365 { 00366 if (row <= col) 00367 { 00368 int64_t r=row; 00369 return kmatrix[r*num_cols - r*(r+1)/2 + col]; 00370 } 00371 else 00372 { 00373 int64_t c=col; 00374 return kmatrix[c*num_cols - c*(c+1)/2 + row]; 00375 } 00376 } 00377 else 00378 { 00379 int64_t r=row; 00380 return kmatrix[r*num_cols+col]; 00381 } 00382 } 00383 00384 private: 00386 void cleanup_custom(); 00387 00388 protected: 00390 float32_t* kmatrix; 00392 int32_t num_rows; 00394 int32_t num_cols; 00396 bool upper_diagonal; 00397 }; 00398 00399 } 00400 #endif /* _CUSTOMKERNEL_H__ */