SparsePolyKernel.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 "kernel/SparsePolyKernel.h"
00014 #include "features/SparseFeatures.h"
00015 
00016 CSparsePolyKernel::CSparsePolyKernel(INT size, INT d, bool i, bool un)
00017 : CSparseKernel<DREAL>(size), degree(d),
00018     inhomogene(i),use_normalization(un), sqrtdiag_lhs(NULL), sqrtdiag_rhs(NULL),
00019     initialized(false)
00020 {
00021 }
00022 
00023 CSparsePolyKernel::CSparsePolyKernel(
00024     CSparseFeatures<DREAL>* l, CSparseFeatures<DREAL>* r,
00025     INT size, INT d, bool i, bool un)
00026 : CSparseKernel<DREAL>(size),degree(d),inhomogene(i), use_normalization(un),
00027     sqrtdiag_lhs(NULL), sqrtdiag_rhs(NULL), initialized(false)
00028 {
00029     init(l,r);
00030 }
00031 
00032 CSparsePolyKernel::~CSparsePolyKernel()
00033 {
00034     cleanup();
00035 }
00036 
00037 bool CSparsePolyKernel::init(CFeatures* l, CFeatures* r)
00038 {
00039     bool result=CSparseKernel<DREAL>::init(l,r);
00040 
00041     initialized = false ;
00042     INT i;
00043 
00044     if (sqrtdiag_lhs != sqrtdiag_rhs)
00045       delete[] sqrtdiag_rhs;
00046     sqrtdiag_rhs=NULL ;
00047     delete[] sqrtdiag_lhs;
00048     sqrtdiag_lhs=NULL ;
00049 
00050     if (use_normalization)
00051     {
00052         sqrtdiag_lhs= new DREAL[lhs->get_num_vectors()];
00053 
00054         for (i=0; i<lhs->get_num_vectors(); i++)
00055             sqrtdiag_lhs[i]=1;
00056 
00057         if (l==r)
00058             sqrtdiag_rhs=sqrtdiag_lhs;
00059         else
00060         {
00061             sqrtdiag_rhs= new DREAL[rhs->get_num_vectors()];
00062             for (i=0; i<rhs->get_num_vectors(); i++)
00063                 sqrtdiag_rhs[i]=1;
00064         }
00065 
00066         this->lhs=(CSparseFeatures<DREAL>*) l;
00067         this->rhs=(CSparseFeatures<DREAL>*) l;
00068 
00069         //compute normalize to 1 values
00070         for (i=0; i<lhs->get_num_vectors(); i++)
00071         {
00072             sqrtdiag_lhs[i]=sqrt(compute(i,i));
00073 
00074             //trap divide by zero exception
00075             if (sqrtdiag_lhs[i]==0)
00076                 sqrtdiag_lhs[i]=1e-16;
00077         }
00078 
00079         // if lhs is different from rhs (train/test data)
00080         // compute also the normalization for rhs
00081         if (sqrtdiag_lhs!=sqrtdiag_rhs)
00082         {
00083             this->lhs=(CSparseFeatures<DREAL>*) r;
00084             this->rhs=(CSparseFeatures<DREAL>*) r;
00085 
00086             //compute normalize to 1 values
00087             for (i=0; i<rhs->get_num_vectors(); i++)
00088             {
00089                 sqrtdiag_rhs[i]=sqrt(compute(i,i));
00090 
00091                 //trap divide by zero exception
00092                 if (sqrtdiag_rhs[i]==0)
00093                     sqrtdiag_rhs[i]=1e-16;
00094             }
00095         }
00096     }
00097 
00098     this->lhs=(CSparseFeatures<DREAL>*) l;
00099     this->rhs=(CSparseFeatures<DREAL>*) r;
00100 
00101     initialized = true;
00102     return result;
00103 }
00104   
00105 void CSparsePolyKernel::cleanup()
00106 {
00107     if (sqrtdiag_lhs != sqrtdiag_rhs)
00108         delete[] sqrtdiag_rhs;
00109     sqrtdiag_rhs=NULL;
00110 
00111     delete[] sqrtdiag_lhs;
00112     sqrtdiag_lhs=NULL;
00113 
00114     initialized=false;
00115 
00116     CKernel::cleanup();
00117 }
00118 
00119 bool CSparsePolyKernel::load_init(FILE* src)
00120 {
00121     return false;
00122 }
00123 
00124 bool CSparsePolyKernel::save_init(FILE* dest)
00125 {
00126     return false;
00127 }
00128   
00129 DREAL CSparsePolyKernel::compute(INT idx_a, INT idx_b)
00130 {
00131   INT alen=0;
00132   INT blen=0;
00133   bool afree=false;
00134   bool bfree=false;
00135 
00136   TSparseEntry<DREAL>* avec=((CSparseFeatures<DREAL>*) lhs)->get_sparse_feature_vector(idx_a, alen, afree);
00137   TSparseEntry<DREAL>* bvec=((CSparseFeatures<DREAL>*) rhs)->get_sparse_feature_vector(idx_b, blen, bfree);
00138 
00139   DREAL sqrt_a= 1.0;
00140   DREAL sqrt_b= 1.0;
00141   if (initialized && use_normalization)
00142   {
00143       sqrt_a=sqrtdiag_lhs[idx_a] ;
00144       sqrt_b=sqrtdiag_rhs[idx_b] ;
00145   }
00146 
00147   DREAL sqrt_both=sqrt_a*sqrt_b;
00148   
00149   DREAL result=((CSparseFeatures<DREAL>*) lhs)->sparse_dot(1.0,avec, alen, bvec, blen);
00150 
00151   if (inhomogene)
00152       result+=1;
00153 
00154   DREAL re=result;
00155 
00156   for (INT j=1; j<degree; j++)
00157       result*=re;
00158 
00159   ((CSparseFeatures<DREAL>*) lhs)->free_feature_vector(avec, idx_a, afree);
00160   ((CSparseFeatures<DREAL>*) rhs)->free_feature_vector(bvec, idx_b, bfree);
00161 
00162   return result/sqrt_both;
00163 }

SHOGUN Machine Learning Toolbox - Documentation