MahalanobisDistance.cpp

Go to the documentation of this file.
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) 2012 Fernando José Iglesias García
00008  * Copyright (C) 2012 Fernando José Iglesias García
00009  */
00010 
00011 #ifdef HAVE_LAPACK
00012 
00013 #include <shogun/lib/common.h>
00014 #include <shogun/io/SGIO.h>
00015 #include <shogun/distance/MahalanobisDistance.h>
00016 #include <shogun/features/Features.h>
00017 #include <shogun/mathematics/Math.h>
00018 #include <shogun/mathematics/lapack.h>
00019 
00020 using namespace shogun;
00021 
00022 CMahalanobisDistance::CMahalanobisDistance() : CRealDistance()
00023 {
00024     init();
00025 }
00026 
00027 CMahalanobisDistance::CMahalanobisDistance(CDenseFeatures<float64_t>* l, CDenseFeatures<float64_t>* r)
00028 : CRealDistance()
00029 {
00030     init();
00031     init(l, r);
00032 }
00033 
00034 CMahalanobisDistance::~CMahalanobisDistance()
00035 {
00036     cleanup();
00037 }
00038 
00039 bool CMahalanobisDistance::init(CFeatures* l, CFeatures* r)
00040 {
00041     CRealDistance::init(l, r);
00042 
00043 
00044     if ( l == r)
00045     {
00046         mean = ((CDenseFeatures<float64_t>*) l)->get_mean();
00047         icov  = ((CDenseFeatures<float64_t>*) l)->get_cov();
00048     }
00049     else
00050     {
00051         mean = ((CDenseFeatures<float64_t>*) l)->get_mean((CDotFeatures*) lhs, (CDotFeatures*) rhs);
00052         icov = CDotFeatures::compute_cov((CDotFeatures*) lhs, (CDotFeatures*) rhs);
00053     }
00054 
00055     SGMatrix<float64_t>::inverse(icov);
00056 
00057     return true;
00058 }
00059 
00060 void CMahalanobisDistance::cleanup()
00061 {
00062 }
00063 
00064 float64_t CMahalanobisDistance::compute(int32_t idx_a, int32_t idx_b)
00065 {
00066 
00067     SGVector<float64_t> bvec = ((CDenseFeatures<float64_t>*) rhs)->
00068         get_feature_vector(idx_b);
00069 
00070     SGVector<float64_t> diff;
00071     SGVector<float64_t> avec;
00072 
00073     if (use_mean)
00074         diff = mean.clone();
00075     else
00076     {
00077         avec = ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a);
00078         diff=avec.clone();
00079     }
00080 
00081     ASSERT(diff.vlen == bvec.vlen);
00082 
00083     for (int32_t i=0; i < diff.vlen; i++)
00084         diff[i] = bvec.vector[i] - diff[i];
00085 
00086     SGVector<float64_t> v = diff.clone();
00087     cblas_dgemv(CblasColMajor, CblasNoTrans,
00088         icov.num_rows, icov.num_cols, 1.0, icov.matrix,
00089         diff.vlen, diff.vector, 1, 0.0, v.vector, 1);
00090 
00091     float64_t result = cblas_ddot(v.vlen, v.vector, 1, diff.vector, 1);
00092 
00093     if (!use_mean)
00094         ((CDenseFeatures<float64_t>*) lhs)->free_feature_vector(avec, idx_a);
00095 
00096     ((CDenseFeatures<float64_t>*) rhs)->free_feature_vector(bvec, idx_b);
00097 
00098     if (disable_sqrt)
00099         return result;
00100     else
00101         return CMath::sqrt(result);
00102 }
00103 
00104 void CMahalanobisDistance::init()
00105 {
00106     disable_sqrt=false;
00107     use_mean=false;
00108 
00109     m_parameters->add(&disable_sqrt, "disable_sqrt", "If sqrt shall not be applied.");
00110     m_parameters->add(&use_mean, "use_mean", "If distance shall be computed between mean vector and vector from rhs or between lhs and rhs.");
00111 }
00112 
00113 #endif /* HAVE_LAPACK */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation