CMS 3D CMS Logo

matchOneToOne.h
Go to the documentation of this file.
1 //
2 // Utility function for matching elements of one vector to another
3 // using best matching distance. All pairwise distances are calculated
4 // and then sorted; the best match corresponds to the smallest
5 // distance. Both matched elements are removed from the pool,
6 // then the best match is found among the remaining elements, etc.
7 //
8 // I. Volobouev
9 // April 2008
10 
11 #ifndef RecoJets_FFTJetAlgorithms_matchOneToOne_h
12 #define RecoJets_FFTJetAlgorithms_matchOneToOne_h
13 
14 #include <vector>
15 #include <algorithm>
16 
17 namespace fftjetcms {
18  namespace Private {
20  double distance;
21  unsigned i1;
22  unsigned i2;
23 
24  inline bool operator<(const matchOneToOne_MatchInfo& r) const { return distance < r.distance; }
25 
26  inline bool operator>(const matchOneToOne_MatchInfo& r) const { return distance > r.distance; }
27  };
28  } // namespace Private
29 
30  //
31  // (*matchFrom1To2)[idx] will be set to the index of the element in v2
32  // which corresponds to the element at index "idx" in v1. If no match
33  // to the element at index "idx" in v1 is found, (*matchFrom1To2)[idx]
34  // is set to -1. All non-negative (*matchFrom1To2)[idx] values will be
35  // unique. The function returns the total number of matches made.
36  //
37  template <class T1, class T2, class DistanceCalculator>
38  unsigned matchOneToOne(const std::vector<T1>& v1,
39  const std::vector<T2>& v2,
40  const DistanceCalculator& calc,
41  std::vector<int>* matchFrom1To2,
42  const double maxMatchingDistance = 1.0e300) {
43  unsigned nused = 0;
44  matchFrom1To2->clear();
45 
46  const unsigned n1 = v1.size();
47  if (n1) {
48  matchFrom1To2->reserve(n1);
49  for (unsigned i1 = 0; i1 < n1; ++i1)
50  matchFrom1To2->push_back(-1);
51 
52  const unsigned n2 = v2.size();
53  if (n2) {
54  const unsigned nmatches = n1 * n2;
55  std::vector<Private::matchOneToOne_MatchInfo> distanceTable(nmatches);
56  std::vector<int> taken2(n2);
57 
58  for (unsigned i2 = 0; i2 < n2; ++i2)
59  taken2[i2] = 0;
60 
62  for (unsigned i1 = 0; i1 < n1; ++i1)
63  for (unsigned i2 = 0; i2 < n2; ++i2) {
64  m = &distanceTable[i1 * n2 + i2];
65  m->distance = calc(v1[i1], v2[i2]);
66  m->i1 = i1;
67  m->i2 = i2;
68  }
69 
70  std::sort(distanceTable.begin(), distanceTable.end());
71  for (unsigned i = 0; i < nmatches && nused < n1 && nused < n2; ++i) {
72  m = &distanceTable[i];
73  if (m->distance > maxMatchingDistance)
74  break;
75  if ((*matchFrom1To2)[m->i1] < 0 && !taken2[m->i2]) {
76  (*matchFrom1To2)[m->i1] = static_cast<int>(m->i2);
77  taken2[m->i2] = 1;
78  ++nused;
79  }
80  }
81  }
82  }
83 
84  return nused;
85  }
86 } // namespace fftjetcms
87 
88 #endif // RecoJets_FFTJetAlgorithms_matchOneToOne_h
unsigned matchOneToOne(const std::vector< T1 > &v1, const std::vector< T2 > &v2, const DistanceCalculator &calc, std::vector< int > *matchFrom1To2, const double maxMatchingDistance=1.0e300)
Definition: matchOneToOne.h:38
bool operator>(const matchOneToOne_MatchInfo &r) const
Definition: matchOneToOne.h:26
bool operator<(const matchOneToOne_MatchInfo &r) const
Definition: matchOneToOne.h:24