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 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 "lib/Mathematics.h" 00015 #include "lib/common.h" 00016 #include "distance/Distance.h" 00017 #include "features/Features.h" 00018 00019 namespace shogun 00020 { 00029 class CCustomDistance: public CDistance 00030 { 00031 public: 00033 CCustomDistance(); 00034 00040 CCustomDistance(CDistance* d); 00041 00052 CCustomDistance( 00053 const float64_t* dm, int32_t rows, int32_t cols); 00054 00065 CCustomDistance( 00066 const float32_t* dm, int32_t rows, int32_t cols); 00067 00068 virtual ~CCustomDistance(); 00069 00080 virtual bool dummy_init(int32_t rows, int32_t cols); 00081 00088 virtual bool init(CFeatures* l, CFeatures* r); 00089 00091 virtual void cleanup(); 00092 00097 inline virtual EDistanceType get_distance_type() { return D_CUSTOM; } 00098 00103 inline virtual EFeatureType get_feature_type() { return F_ANY; } 00104 00109 inline virtual EFeatureClass get_feature_class() { return C_ANY; } 00110 00115 virtual const char* get_name() const { return "CustomDistance"; } 00116 00127 bool set_triangle_distance_matrix_from_triangle( 00128 const float64_t* dm, int32_t len) 00129 { 00130 return set_triangle_distance_matrix_from_triangle_generic(dm, len); 00131 } 00132 00143 bool set_triangle_distance_matrix_from_triangle( 00144 const float32_t* dm, int32_t len) 00145 { 00146 return set_triangle_distance_matrix_from_triangle_generic(dm, len); 00147 } 00148 00159 template <class T> 00160 bool set_triangle_distance_matrix_from_triangle_generic( 00161 const T* dm, int64_t len) 00162 { 00163 ASSERT(dm); 00164 ASSERT(len>0); 00165 00166 int64_t cols = (int64_t) floor(-0.5 + CMath::sqrt(0.25+2*len)); 00167 00168 int64_t int32_max=2147483647; 00169 00170 if (cols> int32_max) 00171 SG_ERROR("Matrix larger than %d x %d\n", int32_max); 00172 00173 if (cols*(cols+1)/2 != len) 00174 { 00175 SG_ERROR("dm should be a vector containing a lower triangle matrix, with len=cols*(cols+1)/2 elements\n"); 00176 return false; 00177 } 00178 00179 cleanup_custom(); 00180 SG_DEBUG( "using custom distance of size %dx%d\n", cols,cols); 00181 00182 dmatrix= new float32_t[len]; 00183 00184 upper_diagonal=true; 00185 num_rows=cols; 00186 num_cols=cols; 00187 00188 for (int64_t i=0; i<len; i++) 00189 dmatrix[i]=dm[i]; 00190 00191 dummy_init(num_rows, num_cols); 00192 return true; 00193 } 00194 00205 inline bool set_triangle_distance_matrix_from_full( 00206 const float64_t* dm, int32_t rows, int32_t cols) 00207 { 00208 return set_triangle_distance_matrix_from_full_generic(dm, rows, cols); 00209 } 00210 00221 inline bool set_triangle_distance_matrix_from_full( 00222 const float32_t* dm, int32_t rows, int32_t cols) 00223 { 00224 return set_triangle_distance_matrix_from_full_generic(dm, rows, cols); 00225 } 00226 00235 template <class T> 00236 bool set_triangle_distance_matrix_from_full_generic( 00237 const T* dm, int32_t rows, int32_t cols) 00238 { 00239 ASSERT(rows==cols); 00240 00241 cleanup_custom(); 00242 SG_DEBUG( "using custom distance of size %dx%d\n", cols,cols); 00243 00244 dmatrix= new float32_t[int64_t(cols)*(cols+1)/2]; 00245 00246 upper_diagonal=true; 00247 num_rows=cols; 00248 num_cols=cols; 00249 00250 for (int64_t row=0; row<num_rows; row++) 00251 { 00252 for (int64_t col=row; col<num_cols; col++) 00253 { 00254 int64_t idx=row * num_cols - row*(row+1)/2 + col; 00255 dmatrix[idx]= (float32_t) dm[col*num_rows+row]; 00256 } 00257 } 00258 dummy_init(rows, cols); 00259 return true; 00260 } 00261 00271 bool set_full_distance_matrix_from_full( 00272 const float64_t* dm, int32_t rows, int32_t cols) 00273 { 00274 return set_full_distance_matrix_from_full_generic(dm, rows, cols); 00275 } 00276 00286 bool set_full_distance_matrix_from_full( 00287 const float32_t* dm, int32_t rows, int32_t cols) 00288 { 00289 return set_full_distance_matrix_from_full_generic(dm, rows, cols); 00290 } 00291 00299 template <class T> 00300 bool set_full_distance_matrix_from_full_generic( 00301 const T* dm, int32_t rows, int32_t cols) 00302 { 00303 cleanup_custom(); 00304 SG_DEBUG( "using custom distance of size %dx%d\n", rows,cols); 00305 00306 dmatrix= new float32_t[rows*cols]; 00307 00308 upper_diagonal=false; 00309 num_rows=rows; 00310 num_cols=cols; 00311 00312 for (int32_t row=0; row<num_rows; row++) 00313 { 00314 for (int32_t col=0; col<num_cols; col++) 00315 { 00316 dmatrix[row * num_cols + col]=dm[col*num_rows+row]; 00317 } 00318 } 00319 00320 dummy_init(rows, cols); 00321 return true; 00322 } 00323 00328 virtual inline int32_t get_num_vec_lhs() 00329 { 00330 return num_rows; 00331 } 00332 00337 virtual inline int32_t get_num_vec_rhs() 00338 { 00339 return num_cols; 00340 } 00341 00346 virtual inline bool has_features() 00347 { 00348 return (num_rows>0) && (num_cols>0); 00349 } 00350 00351 protected: 00358 inline virtual float64_t compute(int32_t row, int32_t col) 00359 { 00360 ASSERT(dmatrix); 00361 00362 if (upper_diagonal) 00363 { 00364 if (row <= col) 00365 { 00366 int64_t r=row; 00367 return dmatrix[r*num_cols - r*(r+1)/2 + col]; 00368 } 00369 else 00370 { 00371 int64_t c=col; 00372 return dmatrix[c*num_cols - c*(c+1)/2 + row]; 00373 } 00374 } 00375 else 00376 { 00377 int64_t r=row; 00378 return dmatrix[r*num_cols+col]; 00379 } 00380 } 00381 00382 private: 00383 void init(); 00384 00386 void cleanup_custom(); 00387 00388 protected: 00390 float32_t* dmatrix; 00392 int32_t num_rows; 00394 int32_t num_cols; 00396 bool upper_diagonal; 00397 }; 00398 00399 } 00400 #endif /* _CUSTOMKERNEL_H__ */