Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef RecoJets_FFTJetAlgorithms_matchOneToOne_h
00012 #define RecoJets_FFTJetAlgorithms_matchOneToOne_h
00013
00014 #include <vector>
00015 #include <algorithm>
00016
00017 namespace fftjetcms {
00018 namespace Private {
00019 struct matchOneToOne_MatchInfo
00020 {
00021 double distance;
00022 unsigned i1;
00023 unsigned i2;
00024
00025 inline bool operator<(const matchOneToOne_MatchInfo& r) const
00026 {return distance < r.distance;}
00027
00028 inline bool operator>(const matchOneToOne_MatchInfo& r) const
00029 {return distance > r.distance;}
00030 };
00031 }
00032
00033
00034
00035
00036
00037
00038
00039
00040 template <class T1, class T2, class DistanceCalculator>
00041 unsigned matchOneToOne(const std::vector<T1>& v1, const std::vector<T2>& v2,
00042 const DistanceCalculator& calc,
00043 std::vector<int>* matchFrom1To2,
00044 const double maxMatchingDistance = 1.0e300)
00045 {
00046 unsigned nused = 0;
00047 matchFrom1To2->clear();
00048
00049 const unsigned n1 = v1.size();
00050 if (n1)
00051 {
00052 matchFrom1To2->reserve(n1);
00053 for (unsigned i1=0; i1<n1; ++i1)
00054 matchFrom1To2->push_back(-1);
00055
00056 const unsigned n2 = v2.size();
00057 if (n2)
00058 {
00059 const unsigned nmatches = n1*n2;
00060 std::vector<Private::matchOneToOne_MatchInfo> distanceTable(nmatches);
00061 std::vector<int> taken2(n2);
00062
00063 for (unsigned i2=0; i2<n2; ++i2)
00064 taken2[i2] = 0;
00065
00066 Private::matchOneToOne_MatchInfo* m;
00067 for (unsigned i1=0; i1<n1; ++i1)
00068 for (unsigned i2=0; i2<n2; ++i2)
00069 {
00070 m = &distanceTable[i1*n2+i2];
00071 m->distance = calc(v1[i1], v2[i2]);
00072 m->i1 = i1;
00073 m->i2 = i2;
00074 }
00075
00076 std::sort(distanceTable.begin(), distanceTable.end());
00077 for (unsigned i=0; i<nmatches && nused<n1 && nused<n2; ++i)
00078 {
00079 m = &distanceTable[i];
00080 if (m->distance > maxMatchingDistance)
00081 break;
00082 if ((*matchFrom1To2)[m->i1] < 0 && !taken2[m->i2])
00083 {
00084 (*matchFrom1To2)[m->i1] = static_cast<int>(m->i2);
00085 taken2[m->i2] = 1;
00086 ++nused;
00087 }
00088 }
00089 }
00090 }
00091
00092 return nused;
00093 }
00094 }
00095
00096 #endif // RecoJets_FFTJetAlgorithms_matchOneToOne_h