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 <shogun/mathematics/Math.h>
00015 #include <shogun/lib/common.h>
00016 #include <shogun/kernel/Kernel.h>
00017 #include <shogun/features/Features.h>
00018
00019 namespace shogun
00020 {
00029 class CCustomKernel: public CKernel
00030 {
00031 void init();
00032
00033 public:
00035 CCustomKernel();
00036
00042 CCustomKernel(CKernel* k);
00043
00051 CCustomKernel(SGMatrix<float64_t> km);
00052
00056 virtual ~CCustomKernel();
00057
00068 virtual bool dummy_init(int32_t rows, int32_t cols);
00069
00076 virtual bool init(CFeatures* l, CFeatures* r);
00077
00079 virtual void cleanup();
00080
00085 inline virtual EKernelType get_kernel_type() { return K_CUSTOM; }
00086
00091 inline virtual EFeatureType get_feature_type() { return F_ANY; }
00092
00097 inline virtual EFeatureClass get_feature_class() { return C_ANY; }
00098
00103 virtual const char* get_name() const { return "CustomKernel"; }
00104
00114 bool set_triangle_kernel_matrix_from_triangle(
00115 SGVector<float64_t> tri_kernel_matrix)
00116 {
00117 return set_triangle_kernel_matrix_from_triangle_generic(tri_kernel_matrix);
00118 }
00119
00129 template <class T>
00130 bool set_triangle_kernel_matrix_from_triangle_generic(
00131 SGVector<T> tri_kernel_matrix)
00132 {
00133 ASSERT(tri_kernel_matrix.vector);
00134
00135 int64_t len = tri_kernel_matrix.vlen;
00136 int64_t cols = (int64_t) floor(-0.5 + CMath::sqrt(0.25+2*len));
00137
00138 if (cols*(cols+1)/2 != len)
00139 {
00140 SG_ERROR("km should be a vector containing a lower triangle matrix, with len=cols*(cols+1)/2 elements\n");
00141 return false;
00142 }
00143
00144 cleanup_custom();
00145 SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols);
00146
00147 kmatrix.matrix = SG_MALLOC(float32_t, len);
00148 kmatrix.num_rows=cols;
00149 kmatrix.num_cols=cols;
00150 upper_diagonal=true;
00151
00152 for (int64_t i=0; i<len; i++)
00153 kmatrix.matrix[i]=tri_kernel_matrix.vector[i];
00154
00155 dummy_init(cols,cols);
00156 return true;
00157 }
00158
00166 inline bool set_triangle_kernel_matrix_from_full(
00167 SGMatrix<float64_t> full_kernel_matrix)
00168 {
00169 return set_triangle_kernel_matrix_from_full_generic(full_kernel_matrix);
00170 }
00171
00177 template <class T>
00178 bool set_triangle_kernel_matrix_from_full_generic(
00179 SGMatrix<T> full_kernel_matrix)
00180 {
00181 int32_t rows = full_kernel_matrix.num_rows;
00182 int32_t cols = full_kernel_matrix.num_cols;
00183 ASSERT(rows==cols);
00184
00185 cleanup_custom();
00186 SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols);
00187
00188 kmatrix.matrix = SG_MALLOC(float32_t, int64_t(rows)*cols);
00189 kmatrix.num_rows = rows;
00190 kmatrix.num_cols = cols;
00191 upper_diagonal = false;
00192
00193 for (int64_t row=0; row<rows; row++)
00194 {
00195 for (int64_t col=row; col<cols; col++)
00196 {
00197 int64_t idx=row * cols - row*(row+1)/2 + col;
00198 kmatrix.matrix[idx] = full_kernel_matrix.matrix[col*rows+row];
00199 }
00200 }
00201
00202 dummy_init(rows, cols);
00203 return true;
00204 }
00205
00212 bool set_full_kernel_matrix_from_full(
00213 SGMatrix<float32_t> full_kernel_matrix)
00214 {
00215 cleanup_custom();
00216 kmatrix.matrix = full_kernel_matrix.matrix;
00217 kmatrix.num_rows=full_kernel_matrix.num_rows;
00218 kmatrix.num_cols=full_kernel_matrix.num_cols;
00219 dummy_init(kmatrix.num_rows, kmatrix.num_cols);
00220 return true;
00221 }
00222
00229 bool set_full_kernel_matrix_from_full(
00230 SGMatrix<float64_t> full_kernel_matrix)
00231 {
00232 cleanup_custom();
00233 int32_t rows=full_kernel_matrix.num_rows;
00234 int32_t cols=full_kernel_matrix.num_cols;
00235 SG_DEBUG( "using custom kernel of size %dx%d\n", rows,cols);
00236
00237 kmatrix.matrix = SG_MALLOC(float32_t, int64_t(rows)*cols);
00238 kmatrix.num_rows = rows;
00239 kmatrix.num_cols = cols;
00240 upper_diagonal = false;
00241
00242 for (int32_t row=0; row<rows; row++)
00243 {
00244 for (int32_t col=0; col<cols; col++)
00245 kmatrix.matrix[int64_t(row) * cols + col] =
00246 full_kernel_matrix.matrix[int64_t(col)*rows+row];
00247 }
00248
00249 dummy_init(rows, cols);
00250
00251 full_kernel_matrix.free_matrix();
00252 return true;
00253 }
00254
00259 virtual inline int32_t get_num_vec_lhs()
00260 {
00261 return kmatrix.num_rows;
00262 }
00263
00268 virtual inline int32_t get_num_vec_rhs()
00269 {
00270 return kmatrix.num_cols;
00271 }
00272
00277 virtual inline bool has_features()
00278 {
00279 return (kmatrix.num_rows>0) && (kmatrix.num_cols>0);
00280 }
00281
00282 protected:
00283
00290 inline virtual float64_t compute(int32_t row, int32_t col)
00291 {
00292 ASSERT(kmatrix.matrix);
00293
00294 if (upper_diagonal)
00295 {
00296 if (row <= col)
00297 {
00298 int64_t r=row;
00299 return kmatrix.matrix[r*kmatrix.num_rows - r*(r+1)/2 + col];
00300 }
00301 else
00302 {
00303 int64_t c=col;
00304 return kmatrix.matrix[c*kmatrix.num_cols - c*(c+1)/2 + row];
00305 }
00306 }
00307 else
00308 {
00309 int64_t r=row;
00310 return kmatrix.matrix[r*kmatrix.num_cols+col];
00311 }
00312 }
00313
00314 private:
00315
00317 void cleanup_custom();
00318
00319 protected:
00320
00322 SGMatrix<float32_t> kmatrix;
00323
00325 bool upper_diagonal;
00326 };
00327
00328 }
00329 #endif