SHOGUN
v3.2.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 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00009 */ 00010 00011 #ifndef _CUSTOMDISTANCE_H___ 00012 #define _CUSTOMDISTANCE_H___ 00013 00014 #include <shogun/mathematics/Math.h> 00015 #include <shogun/lib/common.h> 00016 #include <shogun/distance/Distance.h> 00017 #include <shogun/features/Features.h> 00018 00019 namespace shogun 00020 { 00029 class CCustomDistance: public CDistance 00030 { 00031 public: 00033 CCustomDistance(); 00034 00040 CCustomDistance(CDistance* d); 00041 00045 CCustomDistance(const SGMatrix<float64_t> distance_matrix); 00046 00057 CCustomDistance( 00058 const float64_t* dm, int32_t rows, int32_t cols); 00059 00070 CCustomDistance( 00071 const float32_t* dm, int32_t rows, int32_t cols); 00072 00073 virtual ~CCustomDistance(); 00074 00085 virtual bool dummy_init(int32_t rows, int32_t cols); 00086 00093 virtual bool init(CFeatures* l, CFeatures* r); 00094 00096 virtual void cleanup(); 00097 00102 virtual EDistanceType get_distance_type() { return D_CUSTOM; } 00103 00108 virtual EFeatureType get_feature_type() { return F_ANY; } 00109 00114 virtual EFeatureClass get_feature_class() { return C_ANY; } 00115 00120 virtual const char* get_name() const { return "CustomDistance"; } 00121 00132 bool set_triangle_distance_matrix_from_triangle( 00133 const float64_t* dm, int32_t len) 00134 { 00135 return set_triangle_distance_matrix_from_triangle_generic(dm, len); 00136 } 00137 00148 bool set_triangle_distance_matrix_from_triangle( 00149 const float32_t* dm, int32_t len) 00150 { 00151 return set_triangle_distance_matrix_from_triangle_generic(dm, len); 00152 } 00153 00164 template <class T> 00165 bool set_triangle_distance_matrix_from_triangle_generic( 00166 const T* dm, int64_t len) 00167 { 00168 ASSERT(dm) 00169 ASSERT(len>0) 00170 00171 int64_t cols = (int64_t) floor(-0.5 + CMath::sqrt(0.25+2*len)); 00172 00173 int64_t int32_max=2147483647; 00174 00175 if (cols> int32_max) 00176 SG_ERROR("Matrix larger than %d x %d\n", int32_max) 00177 00178 if (cols*(cols+1)/2 != len) 00179 { 00180 SG_ERROR("dm should be a vector containing a lower triangle matrix, with len=cols*(cols+1)/2 elements\n") 00181 return false; 00182 } 00183 00184 cleanup_custom(); 00185 SG_DEBUG("using custom distance of size %dx%d\n", cols,cols) 00186 00187 dmatrix= SG_MALLOC(float32_t, len); 00188 00189 upper_diagonal=true; 00190 num_rows=cols; 00191 num_cols=cols; 00192 00193 for (int64_t i=0; i<len; i++) 00194 dmatrix[i]=dm[i]; 00195 00196 dummy_init(num_rows, num_cols); 00197 return true; 00198 } 00199 00210 inline bool set_triangle_distance_matrix_from_full( 00211 const float64_t* dm, int32_t rows, int32_t cols) 00212 { 00213 return set_triangle_distance_matrix_from_full_generic(dm, rows, cols); 00214 } 00215 00226 inline bool set_triangle_distance_matrix_from_full( 00227 const float32_t* dm, int32_t rows, int32_t cols) 00228 { 00229 return set_triangle_distance_matrix_from_full_generic(dm, rows, cols); 00230 } 00231 00240 template <class T> 00241 bool set_triangle_distance_matrix_from_full_generic( 00242 const T* dm, int32_t rows, int32_t cols) 00243 { 00244 ASSERT(rows==cols) 00245 00246 cleanup_custom(); 00247 SG_DEBUG("using custom distance of size %dx%d\n", cols,cols) 00248 00249 dmatrix= SG_MALLOC(float32_t, int64_t(cols)*(cols+1)/2); 00250 00251 upper_diagonal=true; 00252 num_rows=cols; 00253 num_cols=cols; 00254 00255 for (int64_t row=0; row<num_rows; row++) 00256 { 00257 for (int64_t col=row; col<num_cols; col++) 00258 { 00259 int64_t idx=row * num_cols - row*(row+1)/2 + col; 00260 dmatrix[idx]= (float32_t) dm[col*num_rows+row]; 00261 } 00262 } 00263 dummy_init(rows, cols); 00264 return true; 00265 } 00266 00276 bool set_full_distance_matrix_from_full( 00277 const float64_t* dm, int32_t rows, int32_t cols) 00278 { 00279 return set_full_distance_matrix_from_full_generic(dm, rows, cols); 00280 } 00281 00291 bool set_full_distance_matrix_from_full( 00292 const float32_t* dm, int32_t rows, int32_t cols) 00293 { 00294 return set_full_distance_matrix_from_full_generic(dm, rows, cols); 00295 } 00296 00304 template <class T> 00305 bool set_full_distance_matrix_from_full_generic(const T* dm, int32_t rows, int32_t cols) 00306 { 00307 cleanup_custom(); 00308 SG_DEBUG("using custom distance of size %dx%d\n", rows,cols) 00309 00310 dmatrix=SG_MALLOC(float32_t, rows*cols); 00311 00312 upper_diagonal=false; 00313 num_rows=rows; 00314 num_cols=cols; 00315 00316 for (int32_t row=0; row<num_rows; row++) 00317 { 00318 for (int32_t col=0; col<num_cols; col++) 00319 { 00320 dmatrix[row * num_cols + col]=dm[col*num_rows+row]; 00321 } 00322 } 00323 00324 dummy_init(rows, cols); 00325 return true; 00326 } 00327 00332 virtual int32_t get_num_vec_lhs() 00333 { 00334 return num_rows; 00335 } 00336 00341 virtual int32_t get_num_vec_rhs() 00342 { 00343 return num_cols; 00344 } 00345 00350 virtual bool has_features() 00351 { 00352 return (num_rows>0) && (num_cols>0); 00353 } 00354 00355 protected: 00362 virtual float64_t compute(int32_t row, int32_t col); 00363 00364 private: 00365 void init(); 00366 00368 void cleanup_custom(); 00369 00370 protected: 00372 float32_t* dmatrix; 00374 int32_t num_rows; 00376 int32_t num_cols; 00378 bool upper_diagonal; 00379 }; 00380 00381 } 00382 #endif /* _CUSTOMKERNEL_H__ */