LinearKernel.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 "lib/io.h"
00013 #include "features/Features.h"
00014 #include "features/RealFeatures.h"
00015 #include "kernel/LinearKernel.h"
00016 
00017 CLinearKernel::CLinearKernel(INT size, DREAL s)
00018 : CSimpleKernel<DREAL>(size), scale(s), initialized(false),
00019     normal(NULL), normal_length(0)
00020 {
00021     properties |= KP_LINADD;
00022 }
00023 
00024 CLinearKernel::CLinearKernel(CRealFeatures* l, CRealFeatures* r, DREAL s, INT size)
00025 : CSimpleKernel<DREAL>(size), scale(s), initialized(false),
00026     normal(NULL), normal_length(0)
00027 {
00028     properties |= KP_LINADD;
00029     init(l,r);
00030 }
00031 
00032 CLinearKernel::~CLinearKernel()
00033 {
00034     cleanup();
00035 }
00036 
00037 bool CLinearKernel::init(CFeatures* l, CFeatures* r)
00038 {
00039     CSimpleKernel<DREAL>::init(l, r);
00040 
00041     if (!initialized)
00042         init_rescale();
00043 
00044     SG_INFO( "rescaling kernel by %g (num:%d)\n",scale, CMath::min(l->get_num_vectors(), r->get_num_vectors()));
00045 
00046     return true;
00047 }
00048 
00049 void CLinearKernel::init_rescale()
00050 {
00051     if (scale!=0.0)
00052         return;
00053     double sum=0;
00054     scale=1.0;
00055     for (INT i=0; (i<lhs->get_num_vectors() && i<rhs->get_num_vectors()); i++)
00056             sum+=compute(i, i);
00057 
00058     scale=sum/CMath::min(lhs->get_num_vectors(), rhs->get_num_vectors());
00059     initialized=true;
00060 }
00061 
00062 void CLinearKernel::cleanup()
00063 {
00064     delete_optimization();
00065 
00066     CKernel::cleanup();
00067 }
00068 
00069 bool CLinearKernel::load_init(FILE* src)
00070 {
00071     return false;
00072 }
00073 
00074 bool CLinearKernel::save_init(FILE* dest)
00075 {
00076     return false;
00077 }
00078 
00079 void CLinearKernel::clear_normal()
00080 {
00081     int num = ((CRealFeatures*) lhs)->get_num_features();
00082     if (normal==NULL)
00083     {
00084         normal = new DREAL[num];
00085         normal_length=num;
00086     }
00087 
00088     memset(normal, 0, sizeof(DREAL)*normal_length);
00089 
00090     set_is_initialized(true);
00091 }
00092 
00093 void CLinearKernel::add_to_normal(INT idx, DREAL weight) 
00094 {
00095     INT vlen;
00096     bool vfree;
00097     double* vec=((CRealFeatures*) lhs)->get_feature_vector(idx, vlen, vfree);
00098 
00099     for (int i=0; i<vlen; i++)
00100         normal[i]+= weight*vec[i];
00101 
00102     ((CRealFeatures*) lhs)->free_feature_vector(vec, idx, vfree);
00103 
00104     set_is_initialized(true);
00105 }
00106   
00107 DREAL CLinearKernel::compute(INT idx_a, INT idx_b)
00108 {
00109   INT alen, blen;
00110   bool afree, bfree;
00111 
00112   double* avec=((CRealFeatures*) lhs)->get_feature_vector(idx_a, alen, afree);
00113   double* bvec=((CRealFeatures*) rhs)->get_feature_vector(idx_b, blen, bfree);
00114   
00115   ASSERT(alen==blen);
00116 
00117   DREAL result=CMath::dot(avec, bvec, alen) / scale;
00118 
00119   ((CRealFeatures*) lhs)->free_feature_vector(avec, idx_a, afree);
00120   ((CRealFeatures*) rhs)->free_feature_vector(bvec, idx_b, bfree);
00121 
00122   return result;
00123 }
00124 
00125 bool CLinearKernel::init_optimization(INT num_suppvec, INT* sv_idx, DREAL* alphas) 
00126 {
00127     clear_normal();
00128 
00129     for (int i=0; i<num_suppvec; i++)
00130         add_to_normal(sv_idx[i], alphas[i]);
00131 
00132     set_is_initialized(true);
00133     return true;
00134 }
00135 
00136 bool CLinearKernel::delete_optimization()
00137 {
00138     delete[] normal;
00139     normal_length=0;
00140     normal=NULL;
00141     set_is_initialized(false);
00142 
00143     return true;
00144 }
00145 
00146 DREAL CLinearKernel::compute_optimized(INT idx) 
00147 {
00148     ASSERT(get_is_initialized());
00149 
00150     INT vlen;
00151     bool vfree;
00152     double* vec=((CRealFeatures*) rhs)->get_feature_vector(idx, vlen, vfree);
00153     ASSERT(vlen==normal_length);
00154     DREAL result=CMath::dot(normal,vec, vlen)/scale;
00155     ((CRealFeatures*) rhs)->free_feature_vector(vec, idx, vfree);
00156 
00157     return result;
00158 }

SHOGUN Machine Learning Toolbox - Documentation