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/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