SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
GaussianKernel.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-2010 Soeren Sonnenburg
00008  * Written (W) 2011 Abhinav Maurya
00009  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00010  * Copyright (C) 2010 Berlin Institute of Technology
00011  */
00012 
00013 #include <shogun/lib/common.h>
00014 #include <shogun/base/Parameter.h>
00015 #include <shogun/kernel/GaussianKernel.h>
00016 #include <shogun/features/DotFeatures.h>
00017 #include <shogun/features/DenseFeatures.h>
00018 #include <shogun/io/SGIO.h>
00019 
00020 using namespace shogun;
00021 
00022 CGaussianKernel::CGaussianKernel()
00023     : CDotKernel()
00024 {
00025     init();
00026 }
00027 
00028 CGaussianKernel::CGaussianKernel(int32_t size, float64_t w)
00029 : CDotKernel(size)
00030 {
00031     init();
00032     set_width(w);
00033 }
00034 
00035 CGaussianKernel::CGaussianKernel(
00036     CDotFeatures* l, CDotFeatures* r, float64_t w, int32_t size)
00037 : CDotKernel(size)
00038 {
00039     init();
00040     set_width(w);
00041     init(l,r);
00042 }
00043 
00044 CGaussianKernel::~CGaussianKernel()
00045 {
00046     cleanup();
00047 }
00048 
00049 #include <typeinfo>
00050 CSGObject *CGaussianKernel::shallow_copy() const
00051 {
00052     // TODO: remove this after all the classes get shallow_copy properly implemented
00053     // this assert is to avoid any subclass of CGaussianKernel accidentally called
00054     // with the implement here
00055     ASSERT(typeid(*this) == typeid(CGaussianKernel));
00056     CGaussianKernel *ker = new CGaussianKernel(width, cache_size);
00057     if (lhs)
00058     {
00059         ker->init(lhs, rhs);
00060     }
00061     return ker;
00062 }
00063 
00064 void CGaussianKernel::cleanup()
00065 {
00066     if (sq_lhs != sq_rhs)
00067         SG_FREE(sq_rhs);
00068     sq_rhs = NULL;
00069 
00070     SG_FREE(sq_lhs);
00071     sq_lhs = NULL;
00072 
00073     CKernel::cleanup();
00074 }
00075 
00076 void CGaussianKernel::precompute_squared_helper(float64_t* &buf, CDotFeatures* df)
00077 {
00078     ASSERT(df);
00079     int32_t num_vec=df->get_num_vectors();
00080     buf=SG_MALLOC(float64_t, num_vec);
00081 
00082     for (int32_t i=0; i<num_vec; i++)
00083         buf[i]=df->dot(i,df, i);
00084 }
00085 
00086 bool CGaussianKernel::init(CFeatures* l, CFeatures* r)
00087 {
00089     cleanup();
00090 
00091     CDotKernel::init(l, r);
00092     precompute_squared();
00093     return init_normalizer();
00094 }
00095 
00096 float64_t CGaussianKernel::compute(int32_t idx_a, int32_t idx_b)
00097 {
00098     if (!m_compact)
00099     {
00100         float64_t result=sq_lhs[idx_a]+sq_rhs[idx_b]
00101                 -2*CDotKernel::compute(idx_a, idx_b);
00102         return CMath::exp(-result/width);
00103     }
00104 
00105     int32_t len_features, power;
00106     len_features=((CDenseFeatures<float64_t>*) lhs)->get_num_features();
00107     power=(len_features%2==0) ? (len_features+1):len_features;
00108 
00109     float64_t result=sq_lhs[idx_a]+sq_rhs[idx_b]-2*CDotKernel::compute(idx_a,idx_b);
00110     float64_t result_multiplier=1-(sqrt(result/width))/3;
00111 
00112     if (result_multiplier<=0)
00113         result_multiplier=0;
00114     else
00115         result_multiplier=pow(result_multiplier, power);
00116 
00117     return result_multiplier*exp(-result/width);
00118 }
00119 
00120 void CGaussianKernel::load_serializable_post() throw (ShogunException)
00121 {
00122     CKernel::load_serializable_post();
00123     precompute_squared();
00124 }
00125 
00126 void CGaussianKernel::precompute_squared()
00127 {
00128     if (!lhs || !rhs)
00129         return;
00130 
00131     precompute_squared_helper(sq_lhs, (CDotFeatures*) lhs);
00132 
00133     if (lhs==rhs)
00134         sq_rhs=sq_lhs;
00135     else
00136         precompute_squared_helper(sq_rhs, (CDotFeatures*) rhs);
00137 }
00138 
00139 SGMatrix<float64_t> CGaussianKernel::get_parameter_gradient(TParameter* param,
00140         CSGObject* obj, index_t index)
00141 {
00142 
00143     if (strcmp(param->m_name, "width") == 0 && obj == this)
00144     {
00145         SGMatrix<float64_t> derivative = SGMatrix<float64_t>(num_lhs, num_rhs);
00146 
00147         for (int j = 0; j < num_lhs; j++)
00148         {
00149             for (int k = 0; k < num_rhs; k++)
00150             {
00151                 float64_t element = sq_lhs[j]+sq_rhs[k]-2*CDotKernel::compute(j,k);
00152                 derivative(j,k) = exp(-element/width)*element/(width*width);
00153             }
00154         }
00155 
00156         return derivative;
00157     }
00158 
00159     else
00160     {
00161         return SGMatrix<float64_t>(0,0);
00162     }
00163 }
00164 
00165 void CGaussianKernel::init()
00166 {
00167     set_width(1.0);
00168     set_compact_enabled(false); 
00169     sq_lhs=NULL;
00170     sq_rhs=NULL;
00171     SG_ADD(&width, "width", "Kernel width.", MS_AVAILABLE);
00172     SG_ADD(&m_compact, "compact", "Compact Enabled Option.", MS_AVAILABLE);
00173 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation