SHOGUN
v2.0.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) 2012 Chiyuan Zhang 00008 * Copyright (C) 2012 Chiyuan Zhang 00009 */ 00010 00011 #include <shogun/lib/config.h> 00012 00013 #ifdef HAVE_LAPACK 00014 00015 #include <shogun/multiclass/ecoc/ECOCIHDDecoder.h> 00016 #include <shogun/multiclass/ecoc/ECOCUtil.h> 00017 #include <shogun/mathematics/Math.h> 00018 #include <shogun/mathematics/lapack.h> 00019 00020 using namespace shogun; 00021 00022 00023 int32_t CECOCIHDDecoder::decide_label(const SGVector<float64_t> outputs, const SGMatrix<int32_t> codebook) 00024 { 00025 update_delta_cache(codebook); 00026 00027 SGVector<float64_t> query = binarize(outputs); 00028 SGVector<float64_t> L(codebook.num_cols); 00029 for (int32_t i=0; i < codebook.num_cols; ++i) 00030 L[i] = CECOCUtil::hamming_distance(query.vector, codebook.get_column_vector(i), query.vlen); 00031 00032 SGVector<float64_t> res(codebook.num_cols); 00033 res.zero(); 00034 // res = m_delta * L 00035 cblas_dgemv(CblasColMajor, CblasNoTrans, m_delta.num_cols, m_delta.num_cols, 00036 1, m_delta.matrix, m_delta.num_cols, L.vector, 1, 1, res.vector, 1); 00037 return SGVector<float64_t>::arg_max(res.vector, 1, res.vlen); 00038 } 00039 00040 void CECOCIHDDecoder::update_delta_cache(const SGMatrix<int32_t> codebook) 00041 { 00042 if (codebook.matrix == m_codebook.matrix) 00043 return; // memory address the same 00044 00045 if (codebook.num_cols == m_codebook.num_cols && codebook.num_rows == m_codebook.num_rows) 00046 { 00047 bool the_same = true; 00048 for (int32_t i=0; i < codebook.num_rows && the_same; ++i) 00049 for (int32_t j=0; j < codebook.num_cols && the_same; ++j) 00050 if (codebook(i,j) != m_codebook(i,j)) 00051 the_same = false; 00052 if (the_same) 00053 return; // no need to update delta 00054 } 00055 00056 m_codebook = codebook; // operator= 00057 m_delta = SGMatrix<float64_t>(codebook.num_cols, codebook.num_cols); 00058 m_delta.zero(); 00059 for (int32_t i=0; i < codebook.num_cols; ++i) 00060 { 00061 for (int32_t j=i+1; j < codebook.num_cols; ++j) 00062 { 00063 m_delta(i, j) = m_delta(j, i) = 00064 CECOCUtil::hamming_distance(codebook.get_column_vector(i), codebook.get_column_vector(j), codebook.num_rows); 00065 } 00066 } 00067 00068 // compute inverse of delta 00069 SGVector<int32_t> IPIV(m_delta.num_cols); 00070 clapack_dgetrf(CblasColMajor, m_delta.num_cols, m_delta.num_cols, m_delta.matrix, m_delta.num_cols, IPIV.vector); 00071 clapack_dgetri(CblasColMajor, m_delta.num_cols, m_delta.matrix, m_delta.num_cols, IPIV.vector); 00072 } 00073 00074 #endif // HAVE_LAPACK