CustomKernel.cpp

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  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00009  */
00010 
00011 #include "lib/common.h"
00012 #include "kernel/CustomKernel.h"
00013 #include "features/Features.h"
00014 #include "features/DummyFeatures.h"
00015 #include "lib/io.h"
00016 
00017 using namespace shogun;
00018 
00019 CCustomKernel::CCustomKernel()
00020 : CKernel(10), kmatrix(NULL), num_rows(0), num_cols(0), upper_diagonal(false)
00021 {
00022 }
00023 
00024 CCustomKernel::CCustomKernel(CKernel* k)
00025 : CKernel(10), kmatrix(NULL), num_rows(0), num_cols(0), upper_diagonal(false)
00026 {
00027     if (k->lhs_equals_rhs())
00028     {
00029         int32_t cols=k->get_num_vec_lhs();
00030         SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols);
00031 
00032         kmatrix= new float32_t[cols*(cols+1)/2];
00033 
00034         upper_diagonal=true;
00035         num_rows=cols;
00036         num_cols=cols;
00037 
00038         for (int32_t row=0; row<num_rows; row++)
00039         {
00040             for (int32_t col=row; col<num_cols; col++)
00041                 kmatrix[row * num_cols - row*(row+1)/2 + col]=k->kernel(row,col);
00042         }
00043     }
00044     else
00045     {
00046         int32_t rows=k->get_num_vec_lhs();
00047         int32_t cols=k->get_num_vec_rhs();
00048         kmatrix= new float32_t[rows*cols];
00049 
00050         upper_diagonal=false;
00051         num_rows=rows;
00052         num_cols=cols;
00053 
00054         for (int32_t row=0; row<num_rows; row++)
00055         {
00056             for (int32_t col=0; col<num_cols; col++)
00057             {
00058                 kmatrix[row * num_cols + col]=k->kernel(row,col);
00059             }
00060         }
00061     }
00062 
00063     dummy_init(num_rows, num_cols);
00064 
00065 }
00066 
00067 CCustomKernel::CCustomKernel(const float64_t* km, int32_t rows, int32_t cols)
00068 : CKernel(10), kmatrix(NULL), num_rows(0), num_cols(0), upper_diagonal(false)
00069 {
00070     set_full_kernel_matrix_from_full(km, rows, cols);
00071 }
00072 
00073 CCustomKernel::~CCustomKernel()
00074 {
00075     cleanup();
00076 }
00077 
00078 bool CCustomKernel::dummy_init(int32_t rows, int32_t cols)
00079 {
00080     return init(new CDummyFeatures(rows), new CDummyFeatures(cols));
00081 }
00082 
00083 bool CCustomKernel::init(CFeatures* l, CFeatures* r)
00084 {
00085     CKernel::init(l, r);
00086 
00087     SG_DEBUG( "num_vec_lhs: %d vs num_rows %d\n", l->get_num_vectors(), num_rows);
00088     SG_DEBUG( "num_vec_rhs: %d vs num_cols %d\n", r->get_num_vectors(), num_cols);
00089     ASSERT(l->get_num_vectors()==num_rows);
00090     ASSERT(r->get_num_vectors()==num_cols);
00091     return init_normalizer();
00092 }
00093 
00094 void CCustomKernel::cleanup_custom()
00095 {
00096     SG_DEBUG("cleanup up custom kernel\n");
00097     delete[] kmatrix;
00098     kmatrix=NULL;
00099     upper_diagonal=false;
00100     num_cols=0;
00101     num_rows=0;
00102 }
00103 
00104 void CCustomKernel::cleanup()
00105 {
00106     cleanup_custom();
00107     CKernel::cleanup();
00108 }
00109 
00110 bool CCustomKernel::set_triangle_kernel_matrix_from_triangle(
00111     const float64_t* km, int32_t len)
00112 {
00113     ASSERT(km);
00114     ASSERT(len>0);
00115 
00116     int32_t cols = (int32_t) floor(-0.5 + CMath::sqrt(0.25+2*len));
00117     if (cols*(cols+1)/2 != len)
00118     {
00119         SG_ERROR("km should be a vector containing a lower triangle matrix, with len=cols*(cols+1)/2 elements\n");
00120         return false;
00121     }
00122 
00123 
00124     cleanup_custom();
00125     SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols);
00126 
00127     kmatrix= new float32_t[len];
00128 
00129     upper_diagonal=true;
00130     num_rows=cols;
00131     num_cols=cols;
00132 
00133     for (int32_t i=0; i<len; i++)
00134         kmatrix[i]=km[i];
00135 
00136     dummy_init(num_rows, num_cols);
00137     return true;
00138 }
00139 
00140 bool CCustomKernel::set_triangle_kernel_matrix_from_full(
00141     const float64_t* km, int32_t rows, int32_t cols)
00142 {
00143     ASSERT(rows==cols);
00144 
00145     cleanup_custom();
00146     SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols);
00147 
00148     kmatrix= new float32_t[cols*(cols+1)/2];
00149 
00150     upper_diagonal=true;
00151     num_rows=cols;
00152     num_cols=cols;
00153 
00154     for (int32_t row=0; row<num_rows; row++)
00155     {
00156         for (int32_t col=row; col<num_cols; col++)
00157             kmatrix[row * num_cols - row*(row+1)/2 + col]=km[col*num_rows+row];
00158     }
00159     dummy_init(rows, cols);
00160     return true;
00161 }
00162 
00163 bool CCustomKernel::set_full_kernel_matrix_from_full(
00164     const float64_t* km, int32_t rows, int32_t cols)
00165 {
00166     cleanup_custom();
00167     SG_DEBUG( "using custom kernel of size %dx%d\n", rows,cols);
00168 
00169     kmatrix= new float32_t[rows*cols];
00170 
00171     upper_diagonal=false;
00172     num_rows=rows;
00173     num_cols=cols;
00174 
00175     for (int32_t row=0; row<num_rows; row++)
00176     {
00177         for (int32_t col=0; col<num_cols; col++)
00178         {
00179             kmatrix[row * num_cols + col]=km[col*num_rows+row];
00180         }
00181     }
00182 
00183     dummy_init(rows, cols);
00184     return true;
00185 }

SHOGUN Machine Learning Toolbox - Documentation