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

SHOGUN Machine Learning Toolbox - Documentation