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

SHOGUN Machine Learning Toolbox - Documentation