SHOGUN  v3.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
GaussianARDKernel.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) 2012 Jacob Walker
00008  *
00009  * Adapted from WeightedDegreeRBFKernel.cpp
00010  */
00011 
00012 #include <shogun/lib/common.h>
00013 #include <shogun/kernel/GaussianARDKernel.h>
00014 #include <shogun/features/Features.h>
00015 #include <shogun/io/SGIO.h>
00016 
00017 using namespace shogun;
00018 
00019 CGaussianARDKernel::CGaussianARDKernel() : CLinearARDKernel()
00020 {
00021     init();
00022 }
00023 
00024 
00025 CGaussianARDKernel::CGaussianARDKernel(int32_t size, float64_t width)
00026         : CLinearARDKernel(size), m_width(width)
00027 {
00028     init();
00029 }
00030 
00031 CGaussianARDKernel::CGaussianARDKernel(CDenseFeatures<float64_t>* l,
00032         CDenseFeatures<float64_t>* r, int32_t size, float64_t width)
00033         : CLinearARDKernel(size), m_width(width)
00034 {
00035     init();
00036 }
00037 
00038 bool CGaussianARDKernel::init(CFeatures* l, CFeatures* r)
00039 {
00040     return CLinearARDKernel::init(l,r);
00041 }
00042 
00043 void CGaussianARDKernel::init()
00044 {
00045     m_width=1.0;
00046 
00047     SG_ADD(&m_width, "width", "Kernel width", MS_AVAILABLE, GRADIENT_AVAILABLE);
00048 }
00049 
00050 CGaussianARDKernel::~CGaussianARDKernel()
00051 {
00052 }
00053 
00054 CGaussianARDKernel* CGaussianARDKernel::obtain_from_generic(CKernel* kernel)
00055 {
00056     if (kernel->get_kernel_type()!=K_GAUSSIANARD)
00057     {
00058         SG_SERROR("Provided kernel is not of type CGaussianARDKernel!\n");
00059     }
00060 
00061     /* since an additional reference is returned */
00062     SG_REF(kernel);
00063     return (CGaussianARDKernel*)kernel;
00064 }
00065 
00066 float64_t CGaussianARDKernel::compute(int32_t idx_a, int32_t idx_b)
00067 {
00068     REQUIRE(lhs && rhs, "Features not set!\n")
00069 
00070     SGVector<float64_t> avec=
00071             ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a);
00072     SGVector<float64_t> bvec=
00073         ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b);
00074 
00075     REQUIRE(avec.vlen==bvec.vlen, "Number of right and left hand "
00076             "features must be the same\n");
00077 
00078     float64_t result=0;
00079 
00080     for (index_t i = 0; i < avec.vlen; i++)
00081         result += CMath::pow((avec[i]-bvec[i])*m_weights[i], 2);
00082 
00083     return CMath::exp(-result/m_width);
00084 }
00085 
00086 SGMatrix<float64_t> CGaussianARDKernel::get_parameter_gradient(
00087         const TParameter* param, index_t index)
00088 {
00089     REQUIRE(lhs && rhs, "Features not set!\n")
00090 
00091     if (!strcmp(param->m_name, "weights"))
00092     {
00093         SGMatrix<float64_t> derivative=get_kernel_matrix();
00094 
00095         for (index_t j=0; j<num_lhs; j++)
00096         {
00097             for (index_t k=0; k<num_rhs; k++)
00098             {
00099                 SGVector<float64_t> avec=
00100                     ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(j);
00101                 SGVector<float64_t> bvec=
00102                     ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(k);
00103 
00104                 REQUIRE(avec.vlen==bvec.vlen, "Number of right and left hand "
00105                         "features must be the same\n");
00106 
00107                 float64_t element=compute(j,k);
00108                 float64_t product=CMath::pow((avec[index]-bvec[index]), 2)
00109                         *(m_weights[index]/m_width);
00110 
00111                 derivative(j,k)=-2*element*product;
00112             }
00113         }
00114 
00115         return derivative;
00116     }
00117     else if (!strcmp(param->m_name, "width"))
00118     {
00119         SGMatrix<float64_t> derivative(num_lhs, num_rhs);
00120 
00121         for (index_t j=0; j<num_lhs; j++)
00122         {
00123             for (index_t k=0; k<num_rhs; k++)
00124             {
00125                 SGVector<float64_t> avec=
00126                     ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(j);
00127                 SGVector<float64_t> bvec=
00128                     ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(k);
00129 
00130                 REQUIRE(avec.vlen==bvec.vlen, "Number of right and left hand "
00131                         "features must be the same\n");
00132 
00133                 float64_t result=0;
00134 
00135                 for (index_t i=0; i<avec.vlen; i++)
00136                     result+=CMath::pow((avec[i]-bvec[i])*m_weights[i], 2);
00137 
00138                 derivative(j,k)=CMath::exp(-result/m_width)*
00139                         result/(m_width*m_width);
00140             }
00141         }
00142 
00143         return derivative;
00144     }
00145     else
00146     {
00147         SG_ERROR("Can't compute derivative wrt %s parameter\n", param->m_name);
00148         return SGMatrix<float64_t>();
00149     }
00150 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation