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) 2013 Fernando J. Iglesias Garcia 00008 * Copyright (C) 2013 Fernando J. Iglesias Garcia 00009 */ 00010 00011 #ifdef HAVE_EIGEN3 00012 00013 #include <shogun/distance/CustomMahalanobisDistance.h> 00014 #include <Eigen/Dense> 00015 00016 using namespace shogun; 00017 using namespace Eigen; 00018 00019 CCustomMahalanobisDistance::CCustomMahalanobisDistance() : CRealDistance() 00020 { 00021 register_params(); 00022 } 00023 00024 CCustomMahalanobisDistance::CCustomMahalanobisDistance(CFeatures* l, CFeatures* r, SGMatrix<float64_t> m) 00025 : CRealDistance() 00026 { 00027 register_params(); 00028 CRealDistance::init(l, r); 00029 m_mahalanobis_matrix = m; 00030 } 00031 00032 void CCustomMahalanobisDistance::register_params() 00033 { 00034 SG_ADD(&m_mahalanobis_matrix, "m_mahalanobis_matrix", "Mahalanobis matrix", MS_NOT_AVAILABLE) 00035 } 00036 00037 CCustomMahalanobisDistance::~CCustomMahalanobisDistance() 00038 { 00039 cleanup(); 00040 } 00041 00042 void CCustomMahalanobisDistance::cleanup() 00043 { 00044 } 00045 00046 const char* CCustomMahalanobisDistance::get_name() const 00047 { 00048 return "CustomMahalanobisDistance"; 00049 } 00050 00051 EDistanceType CCustomMahalanobisDistance::get_distance_type() 00052 { 00053 return D_CUSTOMMAHALANOBIS; 00054 } 00055 00056 float64_t CCustomMahalanobisDistance::compute(int32_t idx_a, int32_t idx_b) 00057 { 00058 // Get feature vectors that will be used to compute the distance; casts 00059 // are safe, features are checked to be dense in DenseDistance::init 00060 SGVector<float64_t> avec = static_cast<CDenseFeatures<float64_t>*>(lhs)->get_feature_vector(idx_a); 00061 SGVector<float64_t> bvec = static_cast<CDenseFeatures<float64_t>*>(rhs)->get_feature_vector(idx_b); 00062 00063 REQUIRE(avec.vlen == bvec.vlen, "In CCustomMahalanobisDistance::compute the " 00064 "feature vectors must have the same number of elements") 00065 00066 // Compute the distance between the feature vectors 00067 00068 // Compute the difference vector and wrap in Eigen vector 00069 const VectorXd dvec = Map<const VectorXd>(avec, avec.vlen) - Map<const VectorXd>(bvec, bvec.vlen); 00070 // Wrap Mahalanobis distance in Eigen matrix 00071 Map<const MatrixXd> M(m_mahalanobis_matrix.matrix, m_mahalanobis_matrix.num_rows, 00072 m_mahalanobis_matrix.num_cols); 00073 00074 return dvec.transpose()*M*dvec; 00075 } 00076 00077 #endif /* HAVE_EIGEN3 */