SHOGUN v0.9.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 "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 class CList; 00027 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 (CKernel*) kernel_list->get_first_element(); 00113 } 00114 00120 inline CKernel* get_first_kernel(CListElement*& current) 00121 { 00122 return (CKernel*) 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 (CKernel*) kernel_list->get_last_element(); 00148 } 00149 00154 inline CKernel* get_next_kernel() 00155 { 00156 return (CKernel*) kernel_list->get_next_element(); 00157 } 00158 00164 inline CKernel* get_next_kernel(CListElement*& current) 00165 { 00166 return (CKernel*) 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=(CKernel*) 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* 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 00408 } 00409 } 00410 else 00411 initialized=false; 00412 00413 if (k->get_num_vec_rhs()) 00414 { 00415 if (num_rhs) 00416 ASSERT(num_rhs==k->get_num_vec_rhs()); 00417 num_rhs=k->get_num_vec_rhs(); 00418 00419 if (!get_num_subkernels()) 00420 { 00421 initialized=true; 00422 00423 } 00424 } 00425 else 00426 initialized=false; 00427 } 00428 00429 private: 00430 void init(); 00431 00432 protected: 00434 CList* kernel_list; 00436 int32_t sv_count; 00438 int32_t* sv_idx; 00440 float64_t* sv_weight; 00442 float64_t* subkernel_weights_buffer; 00444 bool append_subkernel_weights; 00446 bool initialized; 00447 }; 00448 } 00449 #endif /* _COMBINEDKERNEL_H__ */