|
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) 2009 Christian Widmer 00008 * Copyright (C) 2009 Max-Planck-Society 00009 */ 00010 00011 #ifndef _MULTITASKKERNELNORMALIZER_H___ 00012 #define _MULTITASKKERNELNORMALIZER_H___ 00013 00014 #include "kernel/KernelNormalizer.h" 00015 #include "kernel/Kernel.h" 00016 #include <algorithm> 00017 00018 00019 00020 namespace shogun 00021 { 00031 class CMultitaskKernelNormalizer: public CKernelNormalizer 00032 { 00033 00034 public: 00035 00038 CMultitaskKernelNormalizer() : scale(1.0) 00039 { 00040 } 00041 00047 CMultitaskKernelNormalizer(std::vector<int32_t> task_lhs, std::vector< 00048 int32_t> task_rhs) : scale(1.0) 00049 { 00050 00051 set_task_vector_lhs(task_lhs); 00052 set_task_vector_rhs(task_rhs); 00053 00054 //run sanity checks 00055 00056 //invoke copy contructor 00057 std::vector<int32_t> unique_tasks_lhs = std::vector<int32_t>( 00058 task_vector_lhs.begin(), task_vector_lhs.end()); 00059 std::vector<int32_t> unique_tasks_rhs = std::vector<int32_t>( 00060 task_vector_rhs.begin(), task_vector_rhs.end()); 00061 00062 //reorder tasks with unique prefix 00063 std::vector<int32_t>::iterator endLocation_lhs = std::unique( 00064 unique_tasks_lhs.begin(), unique_tasks_lhs.end()); 00065 std::vector<int32_t>::iterator endLocation_rhs = std::unique( 00066 unique_tasks_rhs.begin(), unique_tasks_rhs.end()); 00067 00068 //count unique tasks 00069 int32_t num_unique_tasks_lhs = std::distance(unique_tasks_lhs.begin(), 00070 endLocation_lhs); 00071 int32_t num_unique_tasks_rhs = std::distance(unique_tasks_rhs.begin(), 00072 endLocation_rhs); 00073 00074 //initialize members (lhs has always more or equally many tasks than rhs) 00075 num_tasks = num_unique_tasks_lhs; 00076 dependency_matrix = std::vector<float64_t>(num_tasks * num_tasks); 00077 00078 } 00079 00081 virtual ~CMultitaskKernelNormalizer() 00082 { 00083 } 00084 00087 virtual bool init(CKernel* k) 00088 { 00089 00090 //same as first-element normalizer 00091 CFeatures* old_lhs=k->lhs; 00092 CFeatures* old_rhs=k->rhs; 00093 k->lhs=old_lhs; 00094 k->rhs=old_lhs; 00095 00096 if (std::string(k->get_name()) == "WeightedDegree") { 00097 SG_INFO("using first-element normalization\n"); 00098 scale=k->compute(0, 0); 00099 } else { 00100 SG_INFO("no inner normalization for non-WDK kernel\n"); 00101 scale=1.0; 00102 } 00103 00104 k->lhs=old_lhs; 00105 k->rhs=old_rhs; 00106 00107 ASSERT(k); 00108 int32_t num_lhs = k->get_num_vec_lhs(); 00109 int32_t num_rhs = k->get_num_vec_rhs(); 00110 ASSERT(num_lhs>0); 00111 ASSERT(num_rhs>0); 00112 00113 std::cout << "scale: " << scale << std::endl; 00114 00115 return true; 00116 } 00117 00123 inline virtual float64_t normalize(float64_t value, int32_t idx_lhs, 00124 int32_t idx_rhs) 00125 { 00126 00127 //lookup tasks 00128 int32_t task_idx_lhs = task_vector_lhs[idx_lhs]; 00129 int32_t task_idx_rhs = task_vector_rhs[idx_rhs]; 00130 00131 //lookup similarity 00132 float64_t task_similarity = get_task_similarity(task_idx_lhs, 00133 task_idx_rhs); 00134 00135 //take task similarity into account 00136 float64_t similarity = (value/scale) * task_similarity; 00137 00138 00139 return similarity; 00140 00141 } 00142 00147 inline virtual float64_t normalize_lhs(float64_t value, int32_t idx_lhs) 00148 { 00149 SG_ERROR("normalize_lhs not implemented"); 00150 return 0; 00151 } 00152 00157 inline virtual float64_t normalize_rhs(float64_t value, int32_t idx_rhs) 00158 { 00159 SG_ERROR("normalize_rhs not implemented"); 00160 return 0; 00161 } 00162 00163 public: 00164 00166 std::vector<int32_t> get_task_vector_lhs() const 00167 { 00168 return task_vector_lhs; 00169 } 00170 00172 void set_task_vector_lhs(std::vector<int32_t> vec) 00173 { 00174 task_vector_lhs = vec; 00175 } 00176 00178 std::vector<int32_t> get_task_vector_rhs() const 00179 { 00180 return task_vector_rhs; 00181 } 00182 00184 void set_task_vector_rhs(std::vector<int32_t> vec) 00185 { 00186 task_vector_rhs = vec; 00187 } 00188 00190 void set_task_vector(std::vector<int32_t> vec) 00191 { 00192 task_vector_lhs = vec; 00193 task_vector_rhs = vec; 00194 } 00195 00201 float64_t get_task_similarity(int32_t task_lhs, int32_t task_rhs) 00202 { 00203 00204 ASSERT(task_lhs < num_tasks && task_lhs >= 0); 00205 ASSERT(task_rhs < num_tasks && task_rhs >= 0); 00206 00207 return dependency_matrix[task_lhs * num_tasks + task_rhs]; 00208 00209 } 00210 00216 void set_task_similarity(int32_t task_lhs, int32_t task_rhs, 00217 float64_t similarity) 00218 { 00219 00220 ASSERT(task_lhs < num_tasks && task_lhs >= 0); 00221 ASSERT(task_rhs < num_tasks && task_rhs >= 0); 00222 00223 dependency_matrix[task_lhs * num_tasks + task_rhs] = similarity; 00224 00225 } 00226 00228 inline virtual const char* get_name() const 00229 { 00230 return "MultitaskKernelNormalizer"; 00231 } 00232 00233 protected: 00234 00236 std::vector<float64_t> dependency_matrix; 00237 00239 int32_t num_tasks; 00240 00242 std::vector<int32_t> task_vector_lhs; 00243 00245 std::vector<int32_t> task_vector_rhs; 00246 00248 float64_t scale; 00249 00250 }; 00251 } 00252 #endif