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/base/Parameter.h>
00015 #include <shogun/kernel/GaussianKernel.h>
00016 #include <shogun/features/DotFeatures.h>
00017 #include <shogun/features/SimpleFeatures.h>
00018 #include <shogun/io/SGIO.h>
00019
00020 using namespace shogun;
00021
00022 CGaussianKernel::CGaussianKernel()
00023 : CDotKernel()
00024 {
00025 init();
00026 }
00027
00028 CGaussianKernel::CGaussianKernel(int32_t size, float64_t w)
00029 : CDotKernel(size)
00030 {
00031 init();
00032 set_width(w);
00033 }
00034
00035 CGaussianKernel::CGaussianKernel(
00036 CDotFeatures* l, CDotFeatures* r, float64_t w, int32_t size)
00037 : CDotKernel(size)
00038 {
00039 init();
00040 set_width(w);
00041 init(l,r);
00042 }
00043
00044 CGaussianKernel::~CGaussianKernel()
00045 {
00046 cleanup();
00047 }
00048
00049 void CGaussianKernel::cleanup()
00050 {
00051 if (sq_lhs != sq_rhs)
00052 SG_FREE(sq_rhs);
00053 sq_rhs = NULL;
00054
00055 SG_FREE(sq_lhs);
00056 sq_lhs = NULL;
00057
00058 CKernel::cleanup();
00059 }
00060
00061 void CGaussianKernel::precompute_squared_helper(float64_t* &buf, CDotFeatures* df)
00062 {
00063 ASSERT(df);
00064 int32_t num_vec=df->get_num_vectors();
00065 buf=SG_MALLOC(float64_t, num_vec);
00066
00067 for (int32_t i=0; i<num_vec; i++)
00068 buf[i]=df->dot(i,df, i);
00069 }
00070
00071 bool CGaussianKernel::init(CFeatures* l, CFeatures* r)
00072 {
00074 cleanup();
00075
00076 CDotKernel::init(l, r);
00077 precompute_squared();
00078 return init_normalizer();
00079 }
00080
00081 float64_t CGaussianKernel::compute(int32_t idx_a, int32_t idx_b)
00082 {
00083 if (!m_compact)
00084 {
00085 float64_t result=sq_lhs[idx_a]+sq_rhs[idx_b]
00086 -2*CDotKernel::compute(idx_a, idx_b);
00087 return CMath::exp(-result/width);
00088 }
00089
00090 int32_t len_features, power;
00091 len_features=((CSimpleFeatures<float64_t>*) lhs)->get_num_features();
00092 power=(len_features%2==0) ? (len_features+1):len_features;
00093
00094 float64_t result=sq_lhs[idx_a]+sq_rhs[idx_b]-2*CDotKernel::compute(idx_a,idx_b);
00095 float64_t result_multiplier=1-(sqrt(result/width))/3;
00096
00097 if (result_multiplier<=0)
00098 result_multiplier=0;
00099 else
00100 result_multiplier=pow(result_multiplier, power);
00101
00102 return result_multiplier*exp(-result/width);
00103 }
00104
00105 void CGaussianKernel::load_serializable_post(void) throw (ShogunException)
00106 {
00107 CKernel::load_serializable_post();
00108 precompute_squared();
00109 }
00110
00111 void CGaussianKernel::precompute_squared()
00112 {
00113 if (!lhs || !rhs)
00114 return;
00115
00116 precompute_squared_helper(sq_lhs, (CDotFeatures*) lhs);
00117
00118 if (lhs==rhs)
00119 sq_rhs=sq_lhs;
00120 else
00121 precompute_squared_helper(sq_rhs, (CDotFeatures*) rhs);
00122 }
00123
00124 void CGaussianKernel::init()
00125 {
00126 set_width(1.0);
00127 set_compact_enabled(false);
00128 sq_lhs=NULL;
00129 sq_rhs=NULL;
00130 SG_ADD(&width, "width", "Kernel width.", MS_AVAILABLE);
00131 SG_ADD(&m_compact, "compact", "Compact Enabled Option.", MS_AVAILABLE);
00132 }