|
SHOGUN v0.9.3
|
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 "lib/List.h" 00016 #include "lib/io.h" 00017 #include "kernel/Kernel.h" 00018 00019 #include "features/Features.h" 00020 #include "features/CombinedFeatures.h" 00021 00022 namespace shogun 00023 { 00024 class CFeatures; 00025 class CCombinedFeatures; 00026 template <class T> class CList; 00027 template <class T> class CListElement; 00046 class CCombinedKernel : public CKernel 00047 { 00048 public: 00055 CCombinedKernel(int32_t size=10, bool append_subkernel_weights=false); 00056 00057 virtual ~CCombinedKernel(); 00058 00065 virtual bool init(CFeatures* lhs, CFeatures* rhs); 00066 00068 virtual void cleanup(); 00069 00074 virtual EKernelType get_kernel_type() 00075 { 00076 return K_COMBINED; 00077 } 00078 00083 virtual EFeatureType get_feature_type() 00084 { 00085 return F_UNKNOWN; 00086 } 00087 00092 virtual EFeatureClass get_feature_class() 00093 { 00094 return C_COMBINED; 00095 } 00096 00101 virtual const char* get_name() const { return "CombinedKernel"; } 00102 00104 void list_kernels(); 00105 00110 inline CKernel* get_first_kernel() 00111 { 00112 return kernel_list->get_first_element(); 00113 } 00114 00120 inline CKernel* get_first_kernel(CListElement<CKernel*>*¤t) 00121 { 00122 return kernel_list->get_first_element(current); 00123 } 00124 00130 inline CKernel* get_kernel(int32_t idx) 00131 { 00132 CKernel * k = get_first_kernel(); 00133 for (int32_t i=0; i<idx; i++) 00134 { 00135 SG_UNREF(k); 00136 k = get_next_kernel(); 00137 } 00138 return k; 00139 } 00140 00145 inline CKernel* get_last_kernel() 00146 { 00147 return kernel_list->get_last_element(); 00148 } 00149 00154 inline CKernel* get_next_kernel() 00155 { 00156 return kernel_list->get_next_element(); 00157 } 00158 00164 inline CKernel* get_next_kernel(CListElement<CKernel*> *¤t) 00165 { 00166 return kernel_list->get_next_element(current); 00167 } 00168 00174 inline bool insert_kernel(CKernel* k) 00175 { 00176 ASSERT(k); 00177 adjust_num_lhs_rhs_initialized(k); 00178 00179 if (!(k->has_property(KP_LINADD))) 00180 unset_property(KP_LINADD); 00181 00182 return kernel_list->insert_element(k); 00183 } 00184 00190 inline bool append_kernel(CKernel* k) 00191 { 00192 ASSERT(k); 00193 adjust_num_lhs_rhs_initialized(k); 00194 00195 if (!(k->has_property(KP_LINADD))) 00196 unset_property(KP_LINADD); 00197 00198 return kernel_list->append_element(k); 00199 } 00200 00201 00206 inline bool delete_kernel() 00207 { 00208 CKernel* k=kernel_list->delete_element(); 00209 SG_UNREF(k); 00210 00211 if (!k) 00212 { 00213 num_lhs=0; 00214 num_rhs=0; 00215 } 00216 00217 return (k!=NULL); 00218 } 00219 00224 inline bool get_append_subkernel_weights() 00225 { 00226 return append_subkernel_weights; 00227 } 00228 00233 inline int32_t get_num_subkernels() 00234 { 00235 if (append_subkernel_weights) 00236 { 00237 int32_t num_subkernels = 0 ; 00238 CListElement<CKernel*> *current = NULL ; 00239 CKernel * k = get_first_kernel(current) ; 00240 00241 while(k) 00242 { 00243 num_subkernels += k->get_num_subkernels() ; 00244 SG_UNREF(k); 00245 k = get_next_kernel(current) ; 00246 } 00247 return num_subkernels ; 00248 } 00249 else 00250 return kernel_list->get_num_elements(); 00251 } 00252 00257 virtual inline bool has_features() 00258 { 00259 return initialized; 00260 } 00261 00263 virtual void remove_lhs(); 00264 00266 virtual void remove_rhs(); 00267 00269 virtual void remove_lhs_and_rhs(); 00270 00278 virtual bool init_optimization( 00279 int32_t count, int32_t *IDX, float64_t * weights); 00280 00285 virtual bool delete_optimization(); 00286 00292 virtual float64_t compute_optimized(int32_t idx); 00293 00300 virtual void compute_batch( 00301 int32_t num_vec, int32_t* vec_idx, float64_t* target, 00302 int32_t num_suppvec, int32_t* IDX, float64_t* alphas, 00303 float64_t factor=1.0); 00304 00309 static void* compute_optimized_kernel_helper(void* p); 00310 00315 static void* compute_kernel_helper(void* p); 00316 00327 void emulate_compute_batch( 00328 CKernel* k, int32_t num_vec, int32_t* vec_idx, float64_t* target, 00329 int32_t num_suppvec, int32_t* IDX, float64_t* weights); 00330 00336 virtual void add_to_normal(int32_t idx, float64_t weight); 00337 00339 virtual void clear_normal(); 00340 00346 virtual void compute_by_subkernel( 00347 int32_t idx, float64_t * subkernel_contrib); 00348 00354 virtual const float64_t* get_subkernel_weights(int32_t& num_weights); 00355 00361 virtual void get_subkernel_weights(float64_t** weights, int32_t* num_weights); 00362 00368 virtual void set_subkernel_weights( 00369 float64_t* weights, int32_t num_weights); 00370 00375 virtual void set_optimization_type(EOptimizationType t); 00376 00378 bool precompute_subkernels(); 00379 00380 protected: 00387 virtual float64_t compute(int32_t x, int32_t y); 00388 00394 inline void adjust_num_lhs_rhs_initialized(CKernel* k) 00395 { 00396 ASSERT(k); 00397 00398 if (k->get_num_vec_lhs()) 00399 { 00400 if (num_lhs) 00401 ASSERT(num_lhs==k->get_num_vec_lhs()); 00402 num_lhs=k->get_num_vec_lhs(); 00403 00404 if (!get_num_subkernels()) 00405 { 00406 initialized=true; 00407 #ifdef USE_SVMLIGHT 00408 cache_reset(); 00409 #endif //USE_SVMLIGHT 00410 } 00411 } 00412 else 00413 initialized=false; 00414 00415 if (k->get_num_vec_rhs()) 00416 { 00417 if (num_rhs) 00418 ASSERT(num_rhs==k->get_num_vec_rhs()); 00419 num_rhs=k->get_num_vec_rhs(); 00420 00421 if (!get_num_subkernels()) 00422 { 00423 initialized=true; 00424 #ifdef USE_SVMLIGHT 00425 cache_reset(); 00426 #endif //USE_SVMLIGHT 00427 } 00428 } 00429 else 00430 initialized=false; 00431 } 00432 00433 protected: 00435 CList<CKernel*>* kernel_list; 00437 int32_t sv_count; 00439 int32_t* sv_idx; 00441 float64_t* sv_weight; 00443 float64_t* subkernel_weights_buffer; 00445 bool append_subkernel_weights; 00447 bool initialized; 00448 }; 00449 } 00450 #endif /* _COMBINEDKERNEL_H__ */