SHOGUN
v1.1.0
|
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 * Written (W) 1999-2010 Soeren Sonnenburg 00008 * Written (W) 2011 Abhinav Maurya 00009 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00010 * Copyright (C) 2010 Berlin Institute of Technology 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() 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 }