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 2 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2010 Christian Widmer 00008 * Copyright (C) 2010 Max-Planck-Society 00009 */ 00010 00011 #ifndef _MULTITASKKERNELMASKNORMALIZER_H___ 00012 #define _MULTITASKKERNELMASKNORMALIZER_H___ 00013 00014 #include "kernel/KernelNormalizer.h" 00015 #include "kernel/Kernel.h" 00016 00017 namespace shogun 00018 { 00019 00020 00031 class CMultitaskKernelMaskNormalizer: public CKernelNormalizer 00032 { 00033 00034 public: 00035 00038 CMultitaskKernelMaskNormalizer() : CKernelNormalizer(), 00039 scale(1.0), normalization_constant(1.0) 00040 { 00041 } 00042 00048 CMultitaskKernelMaskNormalizer(std::vector<int32_t> task_lhs, 00049 std::vector<int32_t> task_rhs, 00050 std::vector<int32_t> active_tasks_vec) 00051 : CKernelNormalizer(), scale(1.0), normalization_constant(1.0) 00052 { 00053 00054 00055 set_task_vector_lhs(task_lhs); 00056 set_task_vector_rhs(task_rhs); 00057 00058 // set active tasks 00059 for (int32_t i = 0; i != (int32_t)(active_tasks_vec.size()); ++i) 00060 { 00061 active_tasks.insert(active_tasks_vec[i]); 00062 } 00063 00064 } 00065 00066 00068 virtual ~CMultitaskKernelMaskNormalizer() 00069 { 00070 } 00071 00074 virtual bool init(CKernel* k) 00075 { 00076 ASSERT(k); 00077 int32_t num_lhs = k->get_num_vec_lhs(); 00078 int32_t num_rhs = k->get_num_vec_rhs(); 00079 ASSERT(num_lhs>0); 00080 ASSERT(num_rhs>0); 00081 00082 00083 //same as first-element normalizer 00084 CFeatures* old_lhs=k->lhs; 00085 CFeatures* old_rhs=k->rhs; 00086 k->lhs=old_lhs; 00087 k->rhs=old_lhs; 00088 00089 if (std::string(k->get_name()) == "WeightedDegree") { 00090 SG_INFO("using first-element normalization\n"); 00091 scale=k->compute(0, 0); 00092 } else { 00093 SG_INFO("no inner normalization for non-WDK kernel\n"); 00094 scale=1.0; 00095 } 00096 00097 k->lhs=old_lhs; 00098 k->rhs=old_rhs; 00099 00100 00101 return true; 00102 } 00103 00104 00105 00111 inline virtual float64_t normalize(float64_t value, int32_t idx_lhs, int32_t idx_rhs) 00112 { 00113 00114 //lookup tasks 00115 int32_t task_idx_lhs = task_vector_lhs[idx_lhs]; 00116 int32_t task_idx_rhs = task_vector_rhs[idx_rhs]; 00117 00118 //lookup similarity 00119 float64_t task_similarity = get_similarity(task_idx_lhs, task_idx_rhs); 00120 00121 //take task similarity into account 00122 float64_t similarity = (value/scale) * task_similarity; 00123 00124 00125 return similarity; 00126 00127 } 00128 00133 inline virtual float64_t normalize_lhs(float64_t value, int32_t idx_lhs) 00134 { 00135 SG_ERROR("normalize_lhs not implemented"); 00136 return 0; 00137 } 00138 00143 inline virtual float64_t normalize_rhs(float64_t value, int32_t idx_rhs) 00144 { 00145 SG_ERROR("normalize_rhs not implemented"); 00146 return 0; 00147 } 00148 00150 std::vector<int32_t> get_task_vector_lhs() const 00151 { 00152 return task_vector_lhs; 00153 } 00154 00155 00157 void set_task_vector_lhs(std::vector<int32_t> vec) 00158 { 00159 00160 task_vector_lhs.clear(); 00161 00162 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00163 { 00164 task_vector_lhs.push_back(vec[i]); 00165 } 00166 00167 } 00168 00171 std::vector<int32_t> get_task_vector_rhs() const 00172 { 00173 return task_vector_rhs; 00174 } 00175 00176 00178 void set_task_vector_rhs(std::vector<int32_t> vec) 00179 { 00180 00181 task_vector_rhs.clear(); 00182 00183 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00184 { 00185 task_vector_rhs.push_back(vec[i]); 00186 } 00187 00188 } 00189 00191 void set_task_vector(std::vector<int32_t> vec) 00192 { 00193 set_task_vector_lhs(vec); 00194 set_task_vector_rhs(vec); 00195 } 00196 00197 00203 float64_t get_similarity(int32_t task_lhs, int32_t task_rhs) 00204 { 00205 00206 const bool lhs_is_in = active_tasks.find(task_lhs) != active_tasks.end(); 00207 const bool rhs_is_in = active_tasks.find(task_rhs) != active_tasks.end(); 00208 00209 float64_t similarity = 0.0; 00210 00211 if (lhs_is_in && rhs_is_in) 00212 { 00213 similarity = 1.0 / normalization_constant; 00214 } 00215 00216 return similarity; 00217 00218 } 00219 00223 std::vector<int32_t> get_active_tasks() 00224 { 00225 00226 std::vector<int32_t> active_tasks_vec; 00227 00228 // set active tasks 00229 for (std::set<int32_t>::const_iterator it=active_tasks.begin(); it!=active_tasks.end(); it++) 00230 { 00231 active_tasks_vec.push_back(*it); 00232 } 00233 00234 return active_tasks_vec; 00235 } 00236 00240 float64_t get_normalization_constant () const 00241 { 00242 return normalization_constant; 00243 } 00244 00248 float64_t set_normalization_constant(float64_t constant) 00249 { 00250 normalization_constant = constant; 00251 00252 SG_NOTIMPLEMENTED; 00253 return 0.0; 00254 } 00255 00257 inline virtual const char* get_name() const 00258 { 00259 return "MultitaskKernelMaskNormalizer"; 00260 } 00261 00262 00263 00264 protected: 00265 00267 std::set<int32_t> active_tasks; 00268 00270 std::vector<int32_t> task_vector_lhs; 00271 00273 std::vector<int32_t> task_vector_rhs; 00274 00276 float64_t scale; 00277 00279 float64_t normalization_constant; 00280 00281 }; 00282 } 00283 #endif