plugins/base1/se.lu.thep.wenni/trunk/lib/c++_tools/utility/kNNI.cc

Code
Comments
Other
Rev Date Author Line
69 11 Feb 06 jari 1 // $Id$
69 11 Feb 06 jari 2
95 05 Apr 06 jari 3 /*
95 05 Apr 06 jari 4   Copyright (C) 2004 Jari Häkkinen
95 05 Apr 06 jari 5   Copyright (C) 2005 Peter Johansson
95 05 Apr 06 jari 6   Copyright (C) 2006 Jari Häkkinen
95 05 Apr 06 jari 7
95 05 Apr 06 jari 8   This file is part of the thep c++ tools library,
95 05 Apr 06 jari 9                                 http://lev.thep.lu.se/trac/c++_tools
95 05 Apr 06 jari 10
95 05 Apr 06 jari 11   The c++ tools library is free software; you can redistribute it
95 05 Apr 06 jari 12   and/or modify it under the terms of the GNU General Public License
824 26 Nov 08 jari 13   as published by the Free Software Foundation; either version 3 of
95 05 Apr 06 jari 14   the License, or (at your option) any later version.
95 05 Apr 06 jari 15
95 05 Apr 06 jari 16   The c++ tools library is distributed in the hope that it will be
95 05 Apr 06 jari 17   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
95 05 Apr 06 jari 18   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
95 05 Apr 06 jari 19   General Public License for more details.
95 05 Apr 06 jari 20
95 05 Apr 06 jari 21   You should have received a copy of the GNU General Public License
824 26 Nov 08 jari 22   along with WeNNI. If not, see <http://www.gnu.org/licenses/>.
95 05 Apr 06 jari 23 */
95 05 Apr 06 jari 24
69 11 Feb 06 jari 25 #include <c++_tools/utility/kNNI.h>
69 11 Feb 06 jari 26
69 11 Feb 06 jari 27 #include <algorithm>
69 11 Feb 06 jari 28 #include <cmath>
69 11 Feb 06 jari 29 #include <fstream>
69 11 Feb 06 jari 30 #include <vector>
69 11 Feb 06 jari 31
69 11 Feb 06 jari 32 #include <c++_tools/utility/stl_utility.h>
69 11 Feb 06 jari 33
69 11 Feb 06 jari 34 namespace theplu {
69 11 Feb 06 jari 35 namespace utility {
69 11 Feb 06 jari 36
69 11 Feb 06 jari 37   kNNI::kNNI(const gslapi::matrix& matrix,const gslapi::matrix& flag,
819 24 Nov 08 jari 38              const unsigned int neighbours)
69 11 Feb 06 jari 39     : NNI(matrix,flag,neighbours)
69 11 Feb 06 jari 40   {
69 11 Feb 06 jari 41     for (unsigned int i=0; i<weight_.rows(); i++)
69 11 Feb 06 jari 42       for (unsigned int j=0; j<weight_.columns(); j++)
69 11 Feb 06 jari 43         if (!weight_(i,j)) {
69 11 Feb 06 jari 44           mv_rows_.push_back(i);
69 11 Feb 06 jari 45           break;
69 11 Feb 06 jari 46         }
69 11 Feb 06 jari 47     //estimate();
69 11 Feb 06 jari 48   }
69 11 Feb 06 jari 49
69 11 Feb 06 jari 50
69 11 Feb 06 jari 51
69 11 Feb 06 jari 52   // \hat{x_{ij}}=\frac{ \sum_{k=1,N} \frac{x_{kj}}{d_{ki}} }
69 11 Feb 06 jari 53   //                   { \sum_{k=1,N} \frac{1     }{d_{ki}} },
69 11 Feb 06 jari 54   // where N is defined in the paper cited in the NNI class definition
69 11 Feb 06 jari 55   // documentation.
819 24 Nov 08 jari 56   unsigned int kNNI::estimate(void)
69 11 Feb 06 jari 57   {
69 11 Feb 06 jari 58     using namespace std;
69 11 Feb 06 jari 59     for (unsigned int i=0; i<mv_rows_.size(); i++) {
69 11 Feb 06 jari 60       // Jari, avoid copying in next line
819 24 Nov 08 jari 61       vector<pair<unsigned int,double> > distance=calculate_distances(mv_rows_[i]);
69 11 Feb 06 jari 62        sort(distance.begin(),distance.end(),
819 24 Nov 08 jari 63                 pair_value_compare<unsigned int,double>());
69 11 Feb 06 jari 64       for (unsigned int j=0; j<data_.columns(); j++)
69 11 Feb 06 jari 65         if (!weight_(mv_rows_[i],j)) {
819 24 Nov 08 jari 66           vector<unsigned int> knn=nearest_neighbours(j,distance);
69 11 Feb 06 jari 67           double new_value=0.0;
69 11 Feb 06 jari 68           double norm=0.0;
819 24 Nov 08 jari 69           for (vector<unsigned int>::const_iterator k=knn.begin(); k!=knn.end(); k++){
69 11 Feb 06 jari 70             // Jari, a small number needed here, use something standardized.
69 11 Feb 06 jari 71             // Avoid division with zero (perfect match vectors)
69 11 Feb 06 jari 72             double d=(distance[*k].second ? distance[*k].second : 1e-10);
69 11 Feb 06 jari 73             new_value+=data_(distance[*k].first,j)/d;
69 11 Feb 06 jari 74             norm+=1.0/d;
69 11 Feb 06 jari 75           }
69 11 Feb 06 jari 76           // No impute if no contributions from neighbours.
69 11 Feb 06 jari 77           if (norm)
69 11 Feb 06 jari 78             imputed_data_(mv_rows_[i],j)=new_value/norm;
69 11 Feb 06 jari 79           else {
69 11 Feb 06 jari 80             not_imputed_.push_back(i);
69 11 Feb 06 jari 81             // if norm is zero for one column it is zero for all columns
69 11 Feb 06 jari 82             // having zero weight
69 11 Feb 06 jari 83             break;
69 11 Feb 06 jari 84           }
69 11 Feb 06 jari 85         }
69 11 Feb 06 jari 86     }
69 11 Feb 06 jari 87     return not_imputed_.size();
69 11 Feb 06 jari 88   }
69 11 Feb 06 jari 89
69 11 Feb 06 jari 90
69 11 Feb 06 jari 91 }} // of namespace utility and namespace theplu