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 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     SG_DEBUG("cleanup up custom kernel\n");
00102     delete[] kmatrix;
00103     kmatrix=NULL;
00104     upper_diagonal=false;
00105     num_cols=0;
00106     num_rows=0;
00107 }
00108 
00109 void CCustomKernel::cleanup()
00110 {
00111     cleanup_custom();
00112     CKernel::cleanup();
00113 }
00114 
00115 bool CCustomKernel::load_init(FILE* src)
00116 {
00117     return false;
00118 }
00119 
00120 bool CCustomKernel::save_init(FILE* dest)
00121 {
00122     return false;
00123 }
00124 
00125 bool CCustomKernel::set_triangle_kernel_matrix_from_triangle(
00126     const float64_t* km, int32_t len)
00127 {
00128     ASSERT(km);
00129     ASSERT(len>0);
00130 
00131     int32_t cols = (int32_t) floor(-0.5 + CMath::sqrt(0.25+2*len));
00132     if (cols*(cols+1)/2 != len)
00133     {
00134         SG_ERROR("km should be a vector containing a lower triangle matrix, with len=cols*(cols+1)/2 elements\n");
00135         return false;
00136     }
00137 
00138 
00139     cleanup_custom();
00140     SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols);
00141 
00142     kmatrix= new float32_t[len];
00143 
00144     upper_diagonal=true;
00145     num_rows=cols;
00146     num_cols=cols;
00147 
00148     for (int32_t i=0; i<len; i++)
00149         kmatrix[i]=km[i];
00150 
00151     dummy_init(num_rows, num_cols);
00152     return true;
00153 }
00154 
00155 bool CCustomKernel::set_triangle_kernel_matrix_from_full(
00156     const float64_t* km, int32_t rows, int32_t cols)
00157 {
00158     ASSERT(rows==cols);
00159 
00160     cleanup_custom();
00161     SG_DEBUG( "using custom kernel of size %dx%d\n", cols,cols);
00162 
00163     kmatrix= new float32_t[cols*(cols+1)/2];
00164 
00165     upper_diagonal=true;
00166     num_rows=cols;
00167     num_cols=cols;
00168 
00169     for (int32_t row=0; row<num_rows; row++)
00170     {
00171         for (int32_t col=row; col<num_cols; col++)
00172             kmatrix[row * num_cols - row*(row+1)/2 + col]=km[col*num_rows+row];
00173     }
00174     dummy_init(rows, cols);
00175     return true;
00176 }
00177 
00178 bool CCustomKernel::set_full_kernel_matrix_from_full(
00179     const float64_t* km, int32_t rows, int32_t cols)
00180 {
00181     cleanup_custom();
00182     SG_DEBUG( "using custom kernel of size %dx%d\n", rows,cols);
00183 
00184     kmatrix= new float32_t[rows*cols];
00185 
00186     upper_diagonal=false;
00187     num_rows=rows;
00188     num_cols=cols;
00189 
00190     for (int32_t row=0; row<num_rows; row++)
00191     {
00192         for (int32_t col=0; col<num_cols; col++)
00193         {
00194             kmatrix[row * num_cols + col]=km[col*num_rows+row];
00195         }
00196     }
00197 
00198     dummy_init(rows, cols);
00199     return true;
00200 }

SHOGUN Machine Learning Toolbox - Documentation