1 | // $Id: NNI.cc 173 2004-09-28 22:50:09Z jari $ |
---|
2 | |
---|
3 | #include <algorithm> |
---|
4 | #include <cmath> |
---|
5 | #include <fstream> |
---|
6 | |
---|
7 | #include "stl_utility.h" |
---|
8 | #include "NNI.h" |
---|
9 | |
---|
10 | namespace theplu { |
---|
11 | namespace cpptools { |
---|
12 | |
---|
13 | using namespace std; |
---|
14 | |
---|
15 | NNI::NNI(gslapi::matrix& matrix,const gslapi::matrix& weight, |
---|
16 | const u_int neighbours) |
---|
17 | : data_(matrix), imputed_data_(matrix), neighbours_(neighbours), |
---|
18 | weight_(weight) |
---|
19 | { |
---|
20 | } |
---|
21 | |
---|
22 | |
---|
23 | |
---|
24 | // d_{ij}^2=\frac {\sum_{1,N} w_{il} w_{jl} (x_{il}-x_{jl})^2 } |
---|
25 | // {\sum_{l,N} w_{il} w_{jl} } |
---|
26 | vector<pair<u_int,double> > NNI::calculate_distances(const u_int row) const |
---|
27 | { |
---|
28 | vector<pair<u_int,double> > distance; |
---|
29 | for (size_t i=0; i<data_.rows(); i++) |
---|
30 | if (i!=row) { |
---|
31 | double contribs=0; |
---|
32 | pair<u_int,double> this_distance(i,0.0); |
---|
33 | for (size_t j=0; j<data_.columns(); j++) |
---|
34 | // 0 contribution for missing values |
---|
35 | if (weight_(i,j) && weight_(row,j)) { |
---|
36 | double weight_factor=weight_(i,j)*weight_(row,j); |
---|
37 | this_distance.second+=( weight_factor * |
---|
38 | (data_(i,j)-data_(row,j)) * |
---|
39 | (data_(i,j)-data_(row,j)) ); |
---|
40 | contribs+=weight_factor; |
---|
41 | } |
---|
42 | if (contribs) { // ignore lines without any contributions |
---|
43 | this_distance.second=sqrt(this_distance.second/contribs); |
---|
44 | distance.push_back(this_distance); |
---|
45 | } |
---|
46 | } |
---|
47 | return distance; |
---|
48 | } |
---|
49 | |
---|
50 | |
---|
51 | |
---|
52 | vector<u_int> NNI::nearest_neighbours(const u_int column, |
---|
53 | const vector<pair<u_int,double> >& d) const |
---|
54 | { |
---|
55 | vector<u_int> index; |
---|
56 | double contribs=0; |
---|
57 | for (u_int i=0; ((i<d.size()) && |
---|
58 | (contribs+=weight_(d[i].first,column))<=neighbours_); i++) |
---|
59 | if (weight_(d[i].first,column)) |
---|
60 | index.push_back(i); |
---|
61 | return index; |
---|
62 | } |
---|
63 | |
---|
64 | |
---|
65 | }} // of namespace cpptools and namespace theplu |
---|