CustomKernel.h

Go to the documentation of this file.
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  * Written (W) 2012 Heiko Strathmann
00009  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
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 /* _CUSTOMKERNEL_H__ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation