Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
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