Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef _COMBINEDKERNEL_H___
00013 #define _COMBINEDKERNEL_H___
00014
00015 #include <shogun/lib/List.h>
00016 #include <shogun/io/SGIO.h>
00017 #include <shogun/kernel/Kernel.h>
00018
00019 #include <shogun/features/Features.h>
00020 #include <shogun/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 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
00360 virtual SGVector<float64_t> get_subkernel_weights();
00361
00366 virtual void set_subkernel_weights(SGVector<float64_t> weights);
00367
00372 virtual void set_optimization_type(EOptimizationType t);
00373
00375 bool precompute_subkernels();
00376
00380 CCombinedKernel* KernelToCombinedKernel(shogun::CKernel* n)
00381 {
00382 return dynamic_cast<CCombinedKernel*>(n);
00383 }
00384
00393 SGMatrix<float64_t> get_parameter_gradient(TParameter* param,
00394 CSGObject* obj, index_t index);
00395
00400 inline CList* get_list() {SG_REF(kernel_list); return kernel_list;}
00401
00402 protected:
00409 virtual float64_t compute(int32_t x, int32_t y);
00410
00416 inline void adjust_num_lhs_rhs_initialized(CKernel* k)
00417 {
00418 ASSERT(k);
00419
00420 if (k->get_num_vec_lhs())
00421 {
00422 if (num_lhs)
00423 ASSERT(num_lhs==k->get_num_vec_lhs());
00424 num_lhs=k->get_num_vec_lhs();
00425
00426 if (!get_num_subkernels())
00427 {
00428 initialized=true;
00429 #ifdef USE_SVMLIGHT
00430 cache_reset();
00431 #endif //USE_SVMLIGHT
00432 }
00433 }
00434 else
00435 initialized=false;
00436
00437 if (k->get_num_vec_rhs())
00438 {
00439 if (num_rhs)
00440 ASSERT(num_rhs==k->get_num_vec_rhs());
00441 num_rhs=k->get_num_vec_rhs();
00442
00443 if (!get_num_subkernels())
00444 {
00445 initialized=true;
00446 #ifdef USE_SVMLIGHT
00447 cache_reset();
00448 #endif //USE_SVMLIGHT
00449 }
00450 }
00451 else
00452 initialized=false;
00453 }
00454
00455 private:
00456 void init();
00457
00458 protected:
00460 CList* kernel_list;
00462 int32_t sv_count;
00464 int32_t* sv_idx;
00466 float64_t* sv_weight;
00468 float64_t* subkernel_weights_buffer;
00470 bool append_subkernel_weights;
00472 bool initialized;
00473 };
00474 }
00475 #endif