SHOGUN
v1.1.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 inline virtual EDistanceType get_distance_type() { return D_CUSTOM; } 00103 00108 inline virtual EFeatureType get_feature_type() { return F_ANY; } 00109 00114 inline 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( 00306 const T* dm, int32_t rows, int32_t cols) 00307 { 00308 cleanup_custom(); 00309 SG_DEBUG( "using custom distance of size %dx%d\n", rows,cols); 00310 00311 dmatrix= SG_MALLOC(float32_t, rows*cols); 00312 00313 upper_diagonal=false; 00314 num_rows=rows; 00315 num_cols=cols; 00316 00317 for (int32_t row=0; row<num_rows; row++) 00318 { 00319 for (int32_t col=0; col<num_cols; col++) 00320 { 00321 dmatrix[row * num_cols + col]=dm[col*num_rows+row]; 00322 } 00323 } 00324 00325 dummy_init(rows, cols); 00326 return true; 00327 } 00328 00333 virtual inline int32_t get_num_vec_lhs() 00334 { 00335 return num_rows; 00336 } 00337 00342 virtual inline int32_t get_num_vec_rhs() 00343 { 00344 return num_cols; 00345 } 00346 00351 virtual inline bool has_features() 00352 { 00353 return (num_rows>0) && (num_cols>0); 00354 } 00355 00356 protected: 00363 inline virtual float64_t compute(int32_t row, int32_t col) 00364 { 00365 ASSERT(dmatrix); 00366 00367 if (upper_diagonal) 00368 { 00369 if (row <= col) 00370 { 00371 int64_t r=row; 00372 return dmatrix[r*num_cols - r*(r+1)/2 + col]; 00373 } 00374 else 00375 { 00376 int64_t c=col; 00377 return dmatrix[c*num_cols - c*(c+1)/2 + row]; 00378 } 00379 } 00380 else 00381 { 00382 int64_t r=row; 00383 return dmatrix[r*num_cols+col]; 00384 } 00385 } 00386 00387 private: 00388 void init(); 00389 00391 void cleanup_custom(); 00392 00393 protected: 00395 float32_t* dmatrix; 00397 int32_t num_rows; 00399 int32_t num_cols; 00401 bool upper_diagonal; 00402 }; 00403 00404 } 00405 #endif /* _CUSTOMKERNEL_H__ */