Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
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