Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef _CUSTOMKERNEL_H___
00013 #define _CUSTOMKERNEL_H___
00014
00015 #include <shogun/mathematics/Math.h>
00016 #include <shogun/lib/common.h>
00017 #include <shogun/kernel/Kernel.h>
00018 #include <shogun/features/Features.h>
00019
00020 namespace shogun
00021 {
00033 class CCustomKernel: public CKernel
00034 {
00035 void init();
00036
00037 public:
00039 CCustomKernel();
00040
00046 CCustomKernel(CKernel* k);
00047
00055 CCustomKernel(SGMatrix<float64_t> km);
00056
00064 CCustomKernel(SGMatrix<float32_t> km);
00065
00069 virtual ~CCustomKernel();
00070
00083 virtual bool dummy_init(int32_t rows, int32_t cols);
00084
00093 virtual bool init(CFeatures* l, CFeatures* r);
00094
00096 virtual void cleanup();
00097
00099 void cleanup_custom();
00100
00105 virtual EKernelType get_kernel_type() { return K_CUSTOM; }
00106
00111 virtual EFeatureType get_feature_type() { return F_ANY; }
00112
00117 virtual EFeatureClass get_feature_class() { return C_ANY; }
00118
00123 virtual const char* get_name() const { return "CustomKernel"; }
00124
00136 bool set_triangle_kernel_matrix_from_triangle(
00137 SGVector<float64_t> tri_kernel_matrix)
00138 {
00139 if (m_row_subset_stack->has_subsets() || m_col_subset_stack->has_subsets())
00140 {
00141 SG_ERROR("%s::set_triangle_kernel_matrix_from_triangle not"
00142 " possible with subset. Remove first\n", get_name());
00143 }
00144 return set_triangle_kernel_matrix_from_triangle_generic(tri_kernel_matrix);
00145 }
00146
00158 template <class T>
00159 bool set_triangle_kernel_matrix_from_triangle_generic(
00160 SGVector<T> tri_kernel_matrix)
00161 {
00162 if (m_row_subset_stack->has_subsets() || m_col_subset_stack->has_subsets())
00163 {
00164 SG_ERROR("%s::set_triangle_kernel_matrix_from_triangle_generic "
00165 "not possible with subset. Remove first\n", get_name());
00166 }
00167 ASSERT(tri_kernel_matrix.vector);
00168
00169 int64_t len = tri_kernel_matrix.vlen;
00170 int64_t cols = (int64_t) floor(-0.5 + CMath::sqrt(0.25+2*len));
00171
00172 if (cols*(cols+1)/2 != len)
00173 {
00174 SG_ERROR("km should be a vector containing a lower triangle matrix, with len=cols*(cols+1)/2 elements\n");
00175 return false;
00176 }
00177
00178 cleanup_custom();
00179 SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols);
00180
00181 kmatrix=SGMatrix<float32_t>(SG_MALLOC(float32_t, len), cols, cols);
00182 upper_diagonal=true;
00183
00184 for (int64_t i=0; i<len; i++)
00185 kmatrix.matrix[i]=tri_kernel_matrix.vector[i];
00186
00187 dummy_init(cols,cols);
00188 return true;
00189 }
00190
00200 inline bool set_triangle_kernel_matrix_from_full(
00201 SGMatrix<float64_t> full_kernel_matrix)
00202 {
00203 return set_triangle_kernel_matrix_from_full_generic(full_kernel_matrix);
00204 }
00205
00213 template <class T>
00214 bool set_triangle_kernel_matrix_from_full_generic(
00215 SGMatrix<T> full_kernel_matrix)
00216 {
00217 if (m_row_subset_stack->has_subsets() || m_col_subset_stack->has_subsets())
00218 {
00219 SG_ERROR("%s::set_triangle_kernel_matrix_from_full_generic "
00220 "not possible with subset. Remove first\n", get_name());
00221 }
00222
00223 int32_t rows = full_kernel_matrix.num_rows;
00224 int32_t cols = full_kernel_matrix.num_cols;
00225 ASSERT(rows==cols);
00226
00227 cleanup_custom();
00228 SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols);
00229
00230 kmatrix=SGMatrix<float32_t>(SG_MALLOC(float32_t, cols*(cols+1)/2), rows, cols);
00231 upper_diagonal = true;
00232
00233 for (int64_t row=0; row<rows; row++)
00234 {
00235 for (int64_t col=row; col<cols; col++)
00236 {
00237 int64_t idx=row * cols - row*(row+1)/2 + col;
00238 kmatrix.matrix[idx] = full_kernel_matrix.matrix[col*rows+row];
00239 }
00240 }
00241
00242 dummy_init(rows, cols);
00243 return true;
00244 }
00245
00254 bool set_full_kernel_matrix_from_full(
00255 SGMatrix<float32_t> full_kernel_matrix)
00256 {
00257 if (m_row_subset_stack->has_subsets() || m_col_subset_stack->has_subsets())
00258 {
00259 SG_ERROR("%s::set_full_kernel_matrix_from_full "
00260 "not possible with subset. Remove first\n", get_name());
00261 }
00262
00263 cleanup_custom();
00264 kmatrix=full_kernel_matrix;
00265 dummy_init(kmatrix.num_rows, kmatrix.num_cols);
00266 return true;
00267 }
00268
00277 bool set_full_kernel_matrix_from_full(
00278 SGMatrix<float64_t> full_kernel_matrix)
00279 {
00280 if (m_row_subset_stack->has_subsets() || m_col_subset_stack->has_subsets())
00281 {
00282 SG_ERROR("%s::set_full_kernel_matrix_from_full "
00283 "not possible with subset. Remove first\n", get_name());
00284 }
00285
00286 cleanup_custom();
00287 int32_t rows=full_kernel_matrix.num_rows;
00288 int32_t cols=full_kernel_matrix.num_cols;
00289 SG_DEBUG( "using custom kernel of size %dx%d\n", rows,cols);
00290
00291 kmatrix=SGMatrix<float32_t>(rows,cols);
00292 upper_diagonal = false;
00293
00294 for (int64_t i=0; i<int64_t(rows) * cols; i++)
00295 kmatrix.matrix[i]=full_kernel_matrix.matrix[i];
00296
00297 dummy_init(kmatrix.num_rows, kmatrix.num_cols);
00298 return true;
00299 }
00300
00306 virtual void add_row_subset(SGVector<index_t> subset);
00307
00310 virtual void remove_row_subset();
00311
00314 virtual void remove_all_row_subsets();
00315
00317 virtual void row_subset_changed_post();
00318
00324 virtual void add_col_subset(SGVector<index_t> subset);
00325
00328 virtual void remove_col_subset();
00329
00332 virtual void remove_all_col_subsets();
00333
00335 virtual void col_subset_changed_post();
00336
00343 virtual int32_t get_num_vec_lhs()
00344 {
00345 return m_row_subset_stack->has_subsets()
00346 ? m_row_subset_stack->get_size() : num_lhs;
00347 }
00348
00355 virtual int32_t get_num_vec_rhs()
00356 {
00357 return m_col_subset_stack->has_subsets()
00358 ? m_col_subset_stack->get_size() : num_rhs;
00359 }
00360
00367 virtual bool has_features()
00368 {
00369 return (get_num_vec_lhs()>0) && (get_num_vec_rhs()>0);
00370 }
00371
00376 void print_kernel_matrix(const char* prefix="") const;
00377
00382 SGMatrix<float32_t> get_float32_kernel_matrix()
00383 {
00384 return kmatrix;
00385 }
00386
00387 protected:
00388
00397 virtual float64_t compute(int32_t row, int32_t col)
00398 {
00399 ASSERT(kmatrix.matrix);
00400
00401 index_t real_row=m_row_subset_stack->subset_idx_conversion(row);
00402 index_t real_col=m_col_subset_stack->subset_idx_conversion(col);
00403
00404 if (upper_diagonal)
00405 {
00406 if (real_row <= real_col)
00407 {
00408 int64_t r=real_row;
00409 return kmatrix.matrix[r*kmatrix.num_rows - r*(r+1)/2 + real_col];
00410 }
00411 else
00412 {
00413 int64_t c=real_col;
00414 return kmatrix.matrix[c*kmatrix.num_cols - c*(c+1)/2 + real_row];
00415 }
00416 }
00417 else
00418 {
00419 int64_t r=real_row;
00420 return kmatrix.matrix[r*kmatrix.num_cols+real_col];
00421 }
00422 }
00423
00424 protected:
00425
00427 SGMatrix<float32_t> kmatrix;
00428
00430 bool upper_diagonal;
00431
00433 CSubsetStack* m_row_subset_stack;
00435 CSubsetStack* m_col_subset_stack;
00436
00438 bool m_free_km;
00439 };
00440
00441 }
00442 #endif