SHOGUN
v3.2.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-2009 Soeren Sonnenburg 00008 * Written (W) 1999-2008 Gunnar Raetsch 00009 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00010 */ 00011 00012 #ifndef _COMBINEDKERNEL_H___ 00013 #define _COMBINEDKERNEL_H___ 00014 00015 #include <shogun/lib/List.h> 00016 #include <shogun/lib/DynamicObjectArray.h> 00017 #include <shogun/io/SGIO.h> 00018 #include <shogun/kernel/Kernel.h> 00019 00020 #include <shogun/features/Features.h> 00021 #include <shogun/features/CombinedFeatures.h> 00022 00023 namespace shogun 00024 { 00025 class CFeatures; 00026 class CCombinedFeatures; 00027 class CList; 00028 class CListElement; 00047 class CCombinedKernel : public CKernel 00048 { 00049 public: 00056 CCombinedKernel(int32_t size=10, bool append_subkernel_weights=false); 00057 00058 virtual ~CCombinedKernel(); 00059 00068 virtual bool init(CFeatures* lhs, CFeatures* rhs); 00069 00071 virtual void cleanup(); 00072 00077 virtual EKernelType get_kernel_type() 00078 { 00079 return K_COMBINED; 00080 } 00081 00086 virtual EFeatureType get_feature_type() 00087 { 00088 return F_UNKNOWN; 00089 } 00090 00095 virtual EFeatureClass get_feature_class() 00096 { 00097 return C_COMBINED; 00098 } 00099 00104 virtual const char* get_name() const { return "CombinedKernel"; } 00105 00107 void list_kernels(); 00108 00113 inline CKernel* get_first_kernel() 00114 { 00115 return get_kernel(0); 00116 } 00117 00123 inline CKernel* get_kernel(int32_t idx) 00124 { 00125 return (CKernel*) kernel_array->get_element(idx); 00126 } 00127 00132 inline CKernel* get_last_kernel() 00133 { 00134 return get_kernel(get_num_kernels()-1); 00135 } 00136 00144 inline bool insert_kernel(CKernel* k, int32_t idx) 00145 { 00146 ASSERT(k) 00147 adjust_num_lhs_rhs_initialized(k); 00148 00149 if (!(k->has_property(KP_LINADD))) 00150 unset_property(KP_LINADD); 00151 00152 return kernel_array->insert_element(k, idx); 00153 } 00154 00160 inline bool append_kernel(CKernel* k) 00161 { 00162 ASSERT(k) 00163 adjust_num_lhs_rhs_initialized(k); 00164 00165 if (!(k->has_property(KP_LINADD))) 00166 unset_property(KP_LINADD); 00167 00168 int n = get_num_kernels(); 00169 kernel_array->push_back(k); 00170 return n+1==get_num_kernels(); 00171 } 00172 00173 00179 inline bool delete_kernel(int32_t idx) 00180 { 00181 bool succesful_deletion = kernel_array->delete_element(idx); 00182 00183 if (get_num_kernels()==0) 00184 { 00185 num_lhs=0; 00186 num_rhs=0; 00187 } 00188 00189 return succesful_deletion; 00190 } 00191 00196 inline bool get_append_subkernel_weights() 00197 { 00198 return append_subkernel_weights; 00199 } 00200 00205 inline int32_t get_num_subkernels() 00206 { 00207 if (append_subkernel_weights) 00208 { 00209 int32_t num_subkernels = 0; 00210 00211 for (index_t k_idx=0; k_idx<get_num_kernels(); k_idx++) 00212 { 00213 CKernel* k = get_kernel(k_idx); 00214 num_subkernels += k->get_num_subkernels(); 00215 SG_UNREF(k); 00216 } 00217 return num_subkernels; 00218 } 00219 else 00220 return get_num_kernels(); 00221 } 00222 00227 int32_t get_num_kernels() 00228 { 00229 return kernel_array->get_num_elements(); 00230 } 00231 00236 virtual bool has_features() 00237 { 00238 return initialized; 00239 } 00240 00242 virtual void remove_lhs(); 00243 00245 virtual void remove_rhs(); 00246 00248 virtual void remove_lhs_and_rhs(); 00249 00257 virtual bool init_optimization( 00258 int32_t count, int32_t *IDX, float64_t * weights); 00259 00264 virtual bool delete_optimization(); 00265 00271 virtual float64_t compute_optimized(int32_t idx); 00272 00281 virtual void compute_batch( 00282 int32_t num_vec, int32_t* vec_idx, float64_t* target, 00283 int32_t num_suppvec, int32_t* IDX, float64_t* alphas, 00284 float64_t factor=1.0); 00285 00290 static void* compute_optimized_kernel_helper(void* p); 00291 00296 static void* compute_kernel_helper(void* p); 00297 00309 void emulate_compute_batch( 00310 CKernel* k, int32_t num_vec, int32_t* vec_idx, float64_t* target, 00311 int32_t num_suppvec, int32_t* IDX, float64_t* weights); 00312 00318 virtual void add_to_normal(int32_t idx, float64_t weight); 00319 00321 virtual void clear_normal(); 00322 00328 virtual void compute_by_subkernel( 00329 int32_t idx, float64_t * subkernel_contrib); 00330 00336 virtual const float64_t* get_subkernel_weights(int32_t& num_weights); 00337 00342 virtual SGVector<float64_t> get_subkernel_weights(); 00343 00348 virtual void set_subkernel_weights(SGVector<float64_t> weights); 00349 00354 virtual void set_optimization_type(EOptimizationType t); 00355 00357 bool precompute_subkernels(); 00358 00366 static CCombinedKernel* obtain_from_generic(CKernel* kernel); 00367 00375 SGMatrix<float64_t> get_parameter_gradient(const TParameter* param, 00376 index_t index=-1); 00377 00382 inline CDynamicObjectArray* get_array() 00383 { 00384 SG_REF(kernel_array); 00385 return kernel_array; 00386 } 00387 00397 static CList* combine_kernels(CList* kernel_list); 00398 00399 protected: 00406 virtual float64_t compute(int32_t x, int32_t y); 00407 00413 inline void adjust_num_lhs_rhs_initialized(CKernel* k) 00414 { 00415 ASSERT(k) 00416 00417 if (k->get_num_vec_lhs()) 00418 { 00419 if (num_lhs) 00420 ASSERT(num_lhs==k->get_num_vec_lhs()) 00421 num_lhs=k->get_num_vec_lhs(); 00422 00423 if (!get_num_subkernels()) 00424 { 00425 initialized=true; 00426 #ifdef USE_SVMLIGHT 00427 cache_reset(); 00428 #endif //USE_SVMLIGHT 00429 } 00430 } 00431 else 00432 initialized=false; 00433 00434 if (k->get_num_vec_rhs()) 00435 { 00436 if (num_rhs) 00437 ASSERT(num_rhs==k->get_num_vec_rhs()) 00438 num_rhs=k->get_num_vec_rhs(); 00439 00440 if (!get_num_subkernels()) 00441 { 00442 initialized=true; 00443 #ifdef USE_SVMLIGHT 00444 cache_reset(); 00445 #endif //USE_SVMLIGHT 00446 } 00447 } 00448 else 00449 initialized=false; 00450 } 00451 00452 private: 00453 void init(); 00454 00455 protected: 00457 CDynamicObjectArray* kernel_array; 00459 int32_t sv_count; 00461 int32_t* sv_idx; 00463 float64_t* sv_weight; 00465 float64_t* subkernel_weights_buffer; 00467 bool append_subkernel_weights; 00469 bool initialized; 00470 }; 00471 } 00472 #endif /* _COMBINEDKERNEL_H__ */