Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <shogun/lib/common.h>
00015 #include <shogun/base/Parameter.h>
00016 #include <shogun/kernel/GaussianKernel.h>
00017 #include <shogun/features/DotFeatures.h>
00018 #include <shogun/features/DenseFeatures.h>
00019 #include <shogun/io/SGIO.h>
00020
00021 using namespace shogun;
00022
00023 CGaussianKernel::CGaussianKernel()
00024 : CDotKernel()
00025 {
00026 init();
00027 }
00028
00029 CGaussianKernel::CGaussianKernel(int32_t size, float64_t w)
00030 : CDotKernel(size)
00031 {
00032 init();
00033 set_width(w);
00034 }
00035
00036 CGaussianKernel::CGaussianKernel(
00037 CDotFeatures* l, CDotFeatures* r, float64_t w, int32_t size)
00038 : CDotKernel(size)
00039 {
00040 init();
00041 set_width(w);
00042 init(l,r);
00043 }
00044
00045 CGaussianKernel::~CGaussianKernel()
00046 {
00047 cleanup();
00048 }
00049
00050 CGaussianKernel* CGaussianKernel::obtain_from_generic(CKernel* kernel)
00051 {
00052 if (kernel->get_kernel_type()!=K_GAUSSIAN)
00053 {
00054 SG_SERROR("CGaussianKernel::obtain_from_generic(): provided kernel is "
00055 "not of type CGaussianKernel!\n");
00056 }
00057
00058
00059 SG_REF(kernel);
00060 return (CGaussianKernel*)kernel;
00061 }
00062
00063 #include <typeinfo>
00064 CSGObject *CGaussianKernel::shallow_copy() const
00065 {
00066
00067
00068
00069 ASSERT(typeid(*this) == typeid(CGaussianKernel));
00070 CGaussianKernel *ker = new CGaussianKernel(cache_size, width);
00071 if (lhs)
00072 {
00073 ker->init(lhs, rhs);
00074 }
00075 return ker;
00076 }
00077
00078 void CGaussianKernel::cleanup()
00079 {
00080 if (sq_lhs != sq_rhs)
00081 SG_FREE(sq_rhs);
00082 sq_rhs = NULL;
00083
00084 SG_FREE(sq_lhs);
00085 sq_lhs = NULL;
00086
00087 CKernel::cleanup();
00088 }
00089
00090 void CGaussianKernel::precompute_squared_helper(float64_t* &buf, CDotFeatures* df)
00091 {
00092 ASSERT(df);
00093 int32_t num_vec=df->get_num_vectors();
00094 buf=SG_MALLOC(float64_t, num_vec);
00095
00096 for (int32_t i=0; i<num_vec; i++)
00097 buf[i]=df->dot(i,df, i);
00098 }
00099
00100 bool CGaussianKernel::init(CFeatures* l, CFeatures* r)
00101 {
00103 cleanup();
00104
00105 CDotKernel::init(l, r);
00106 precompute_squared();
00107 return init_normalizer();
00108 }
00109
00110 float64_t CGaussianKernel::compute(int32_t idx_a, int32_t idx_b)
00111 {
00112 if (!m_compact)
00113 {
00114 float64_t result=sq_lhs[idx_a]+sq_rhs[idx_b]
00115 -2*CDotKernel::compute(idx_a, idx_b);
00116 return CMath::exp(-result/width);
00117 }
00118
00119 int32_t len_features, power;
00120 len_features=((CDenseFeatures<float64_t>*) lhs)->get_num_features();
00121 power=(len_features%2==0) ? (len_features+1):len_features;
00122
00123 float64_t result=sq_lhs[idx_a]+sq_rhs[idx_b]-2*CDotKernel::compute(idx_a,idx_b);
00124 float64_t result_multiplier=1-(sqrt(result/width))/3;
00125
00126 if (result_multiplier<=0)
00127 result_multiplier=0;
00128 else
00129 result_multiplier=pow(result_multiplier, power);
00130
00131 return result_multiplier*exp(-result/width);
00132 }
00133
00134 void CGaussianKernel::load_serializable_post() throw (ShogunException)
00135 {
00136 CKernel::load_serializable_post();
00137 precompute_squared();
00138 }
00139
00140 void CGaussianKernel::precompute_squared()
00141 {
00142 if (!lhs || !rhs)
00143 return;
00144
00145 precompute_squared_helper(sq_lhs, (CDotFeatures*) lhs);
00146
00147 if (lhs==rhs)
00148 sq_rhs=sq_lhs;
00149 else
00150 precompute_squared_helper(sq_rhs, (CDotFeatures*) rhs);
00151 }
00152
00153 SGMatrix<float64_t> CGaussianKernel::get_parameter_gradient(TParameter* param,
00154 CSGObject* obj, index_t index)
00155 {
00156
00157 if (strcmp(param->m_name, "width") == 0 && obj == this)
00158 {
00159 SGMatrix<float64_t> derivative = SGMatrix<float64_t>(num_lhs, num_rhs);
00160
00161 for (int j = 0; j < num_lhs; j++)
00162 {
00163 for (int k = 0; k < num_rhs; k++)
00164 {
00165 float64_t element = sq_lhs[j]+sq_rhs[k]-2*CDotKernel::compute(j,k);
00166 derivative(j,k) = exp(-element/width)*element/(width*width);
00167 }
00168 }
00169
00170 return derivative;
00171 }
00172
00173 else
00174 {
00175 return SGMatrix<float64_t>(0,0);
00176 }
00177 }
00178
00179 void CGaussianKernel::init()
00180 {
00181 set_width(1.0);
00182 set_compact_enabled(false);
00183 sq_lhs=NULL;
00184 sq_rhs=NULL;
00185 SG_ADD(&width, "width", "Kernel width.", MS_AVAILABLE);
00186 SG_ADD(&m_compact, "compact", "Compact Enabled Option.", MS_AVAILABLE);
00187 }