LinearARDKernel.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/LinearARDKernel.h>
00015 #include <shogun/features/Features.h>
00016 #include <shogun/io/SGIO.h>
00017 
00018 using namespace shogun;
00019 
00020 CLinearARDKernel::CLinearARDKernel()
00021 : CDotKernel()
00022 {
00023     init();
00024 }
00025 
00026 
00027 CLinearARDKernel::CLinearARDKernel(int32_t size)
00028 : CDotKernel(size)
00029 {
00030     init();
00031 }
00032 
00033 CLinearARDKernel::CLinearARDKernel(CDenseFeatures<float64_t>* l,
00034         CDenseFeatures<float64_t>* r,
00035         int32_t size)
00036 : CDotKernel(size)
00037 {
00038     init();
00039     init(l,r);
00040 }
00041 
00042 void CLinearARDKernel::init()
00043 {
00044     m_weights = SGVector<float64_t>();
00045     SG_ADD(&m_weights, "weights", "Feature Weights", MS_AVAILABLE);
00046 }
00047 
00048 CLinearARDKernel::~CLinearARDKernel()
00049 {
00050     CKernel::cleanup();
00051 }
00052 
00053 bool CLinearARDKernel::init(CFeatures* l, CFeatures* r)
00054 {
00055     CDotKernel::init(l, r);
00056 
00057     init_ft_weights();
00058 
00059     return init_normalizer();
00060 }
00061 
00062 void CLinearARDKernel::init_ft_weights()
00063 {
00064     if (!lhs || !rhs)
00065         return;
00066 
00067     int32_t alen, blen;
00068 
00069     alen = ((CDenseFeatures<float64_t>*) lhs)->get_num_features();
00070     blen = ((CDenseFeatures<float64_t>*) rhs)->get_num_features();
00071 
00072     REQUIRE(alen==blen, "Number of Right and Left Hand "\
00073             "Features Must be the Same./n");
00074 
00075     if (m_weights.vlen != alen)
00076     {
00077         m_weights = SGVector<float64_t>(alen);
00078 
00079         for (int32_t i=0; i < alen; i++)
00080             m_weights[i]=1.0;
00081     }
00082 
00083     SG_DEBUG("Initialized weights for LinearARDKernel (%p).\n", this);
00084 
00085 }
00086 
00087 void CLinearARDKernel::set_weight(float64_t w, index_t i)
00088 {
00089     if (i >= m_weights.vlen)
00090     {
00091         SG_ERROR("Index %i out of range for LinearARDKernel."\
00092                  "Number of features is %i.\n", i, m_weights.vlen);
00093     }
00094 
00095     m_weights[i]=w;
00096 }
00097 
00098 float64_t CLinearARDKernel::get_weight(index_t i)
00099 {
00100     if (i >= m_weights.vlen)
00101     {
00102         SG_ERROR("Index %i out of range for LinearARDKernel."\
00103                  "Number of features is %i.\n", i, m_weights.vlen);
00104     }
00105 
00106     return m_weights[i];
00107 }
00108 
00109 float64_t CLinearARDKernel::compute(int32_t idx_a, int32_t idx_b)
00110 {
00111     if (!lhs || !rhs)
00112         SG_ERROR("Features not set!\n");
00113 
00114     SGVector<float64_t> avec
00115         = ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a);
00116     SGVector<float64_t> bvec
00117         = ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b);
00118 
00119     REQUIRE(avec.vlen==bvec.vlen, "Number of Right and Left Hand "\
00120             "Features Must be the Same./n");
00121 
00122     float64_t result=0;
00123 
00124     for (index_t i = 0; i < avec.vlen; i++)
00125         result += avec[i]*bvec[i]*m_weights[i]*m_weights[i];
00126 
00127     return result;
00128 }
00129 
00130 SGMatrix<float64_t> CLinearARDKernel::get_parameter_gradient(TParameter* param,
00131         CSGObject* obj, index_t index)
00132 {
00133     if (!lhs || !rhs)
00134         SG_ERROR("Features not set!\n");
00135 
00136     if (!strcmp(param->m_name, "weights") && obj == this)
00137     {
00138         SGMatrix<float64_t> derivative(num_lhs, num_rhs);
00139 
00140         for (index_t j = 0; j < num_lhs; j++)
00141         {
00142             for (index_t k = 0; k < num_rhs; k++)
00143             {
00144                 SGVector<float64_t> avec
00145                     = ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(j);
00146                 SGVector<float64_t> bvec
00147                     = ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(k);
00148 
00149                 REQUIRE(avec.vlen==bvec.vlen, "Number of Right and Left Hand "\
00150                         "Features Must be the Same./n");
00151 
00152                 derivative(j,k) = avec[index]*bvec[index]*m_weights[index];
00153             }
00154         }
00155         return derivative;
00156     }
00157 
00158     else
00159         return SGMatrix<float64_t>();
00160 }
00161 
00162 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation