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 #include <shogun/base/Parameter.h> 00012 #include <shogun/lib/common.h> 00013 #include <shogun/distance/CustomDistance.h> 00014 #include <shogun/features/Features.h> 00015 #include <shogun/features/DummyFeatures.h> 00016 #include <shogun/io/SGIO.h> 00017 00018 using namespace shogun; 00019 00020 CCustomDistance::CCustomDistance() : CDistance() 00021 { 00022 init(); 00023 } 00024 00025 CCustomDistance::CCustomDistance(CDistance* d) : CDistance() 00026 { 00027 init(); 00028 00029 if (d->lhs_equals_rhs()) 00030 { 00031 int32_t cols=d->get_num_vec_lhs(); 00032 SG_DEBUG("using custom distance of size %dx%d\n", cols,cols) 00033 00034 dmatrix= SG_MALLOC(float32_t, int64_t(cols)*(cols+1)/2); 00035 00036 upper_diagonal=true; 00037 num_rows=cols; 00038 num_cols=cols; 00039 00040 for (int32_t row=0; row<num_rows; row++) 00041 { 00042 for (int32_t col=row; col<num_cols; col++) 00043 dmatrix[int64_t(row) * num_cols - int64_t(row)*(row+1)/2 + col]=d->distance(row,col); 00044 } 00045 } 00046 else 00047 { 00048 int32_t rows=d->get_num_vec_lhs(); 00049 int32_t cols=d->get_num_vec_rhs(); 00050 dmatrix= SG_MALLOC(float32_t, int64_t(rows)*cols); 00051 00052 upper_diagonal=false; 00053 num_rows=rows; 00054 num_cols=cols; 00055 00056 for (int32_t row=0; row<num_rows; row++) 00057 { 00058 for (int32_t col=0; col<num_cols; col++) 00059 dmatrix[int64_t(row) * num_cols + col]=d->distance(row,col); 00060 } 00061 } 00062 00063 dummy_init(num_rows, num_cols); 00064 } 00065 00066 CCustomDistance::CCustomDistance(const SGMatrix<float64_t> distance_matrix) 00067 : CDistance() 00068 { 00069 init(); 00070 set_full_distance_matrix_from_full(distance_matrix.matrix, 00071 distance_matrix.num_rows, 00072 distance_matrix.num_cols); 00073 } 00074 00075 CCustomDistance::CCustomDistance(const float64_t* dm, int32_t rows, int32_t cols) 00076 : CDistance() 00077 { 00078 init(); 00079 set_full_distance_matrix_from_full(dm, rows, cols); 00080 } 00081 00082 CCustomDistance::CCustomDistance(const float32_t* dm, int32_t rows, int32_t cols) 00083 : CDistance() 00084 { 00085 init(); 00086 set_full_distance_matrix_from_full(dm, rows, cols); 00087 } 00088 00089 CCustomDistance::~CCustomDistance() 00090 { 00091 cleanup(); 00092 } 00093 00094 bool CCustomDistance::dummy_init(int32_t rows, int32_t cols) 00095 { 00096 return init(new CDummyFeatures(rows), new CDummyFeatures(cols)); 00097 } 00098 00099 bool CCustomDistance::init(CFeatures* l, CFeatures* r) 00100 { 00101 CDistance::init(l, r); 00102 00103 SG_DEBUG("num_vec_lhs: %d vs num_rows %d\n", l->get_num_vectors(), num_rows) 00104 SG_DEBUG("num_vec_rhs: %d vs num_cols %d\n", r->get_num_vectors(), num_cols) 00105 ASSERT(l->get_num_vectors()==num_rows) 00106 ASSERT(r->get_num_vectors()==num_cols) 00107 return true; 00108 } 00109 00110 00111 void CCustomDistance::cleanup_custom() 00112 { 00113 SG_DEBUG("cleanup up custom distance\n") 00114 SG_FREE(dmatrix); 00115 dmatrix=NULL; 00116 upper_diagonal=false; 00117 num_cols=0; 00118 num_rows=0; 00119 } 00120 00121 void CCustomDistance::init() 00122 { 00123 dmatrix=NULL; 00124 num_rows=0; 00125 num_cols=0; 00126 upper_diagonal=false; 00127 00128 m_parameters->add_matrix(&dmatrix, &num_rows, &num_cols, "dmatrix", "Distance Matrix"); 00129 m_parameters->add(&upper_diagonal, "upper_diagonal", "Upper diagonal"); 00130 } 00131 00132 void CCustomDistance::cleanup() 00133 { 00134 cleanup_custom(); 00135 } 00136 00137 float64_t CCustomDistance::compute(int32_t row, int32_t col) 00138 { 00139 ASSERT(dmatrix) 00140 00141 if (upper_diagonal) 00142 { 00143 if (row <= col) 00144 { 00145 int64_t r=row; 00146 return dmatrix[r*num_cols - r*(r+1)/2 + col]; 00147 } 00148 else 00149 { 00150 int64_t c=col; 00151 return dmatrix[c*num_cols - c*(c+1)/2 + row]; 00152 } 00153 } 00154 else 00155 { 00156 int64_t r=row; 00157 return dmatrix[r*num_cols+col]; 00158 } 00159 }