Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
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 }