yat/utility/kNNI.cc

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