00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <QVVectorMap>
00022
00023 #define SIGNATURE(Vector) (Vector.sum()/sqrt(Vector.size()))
00024
00025 void QVVectorMap::add(const QVVector &vector)
00026 {
00027 insertMulti(SIGNATURE(vector), vector);
00028 }
00029
00030 QVVectorMap::QVVectorMap(const QList<QVVector> & vectors): QMap<double, QVVector>()
00031 {
00032 foreach(QVVector vector, vectors)
00033 add(vector);
00034 };
00035
00036 QList<QVVector> QVVectorMap::getClosestVectors(const QVVector actualVector, const QList<QVVector> &vectors, const int n)
00037 {
00038 QMap<double, QVVector> hash;
00039 foreach(QVVector v, vectors)
00040 hash.insertMulti((v - actualVector).norm2(), v);
00041 return hash.values().mid(0,n);
00042 }
00043
00044 QList<QVVector> QVVectorMap::getClosestVectors(const QVVector &vector, const int maxVectors) const
00045 {
00046 const double vector_signature = SIGNATURE(vector);
00047
00048
00049 if (size() == 0 || maxVectors <= 0)
00050 return QList<QVVector>();
00051
00052 if (size() <= maxVectors)
00053 return values();
00054
00055
00056 int t = 0;
00057 QMap<double, QVVector> closestVectors;
00058 for(QMap<double, QVVector>::const_iterator i = constBegin(); t < maxVectors; ++t, ++i)
00059 closestVectors.insertMulti((vector - i.value()).norm2(), i.value());
00060
00061
00062 double last_key = (--(closestVectors.end())).key();
00063
00064
00065 QMap<double, QVVector>::const_iterator pivot = lowerBound(SIGNATURE(vector));
00066 if (pivot == constEnd())
00067 --pivot;
00068
00069
00070 if (pivot != constBegin())
00071 for (QMap<double, QVVector>::const_iterator i = pivot; i != constBegin(); --i)
00072 {
00073 if (ABS(i.key() - vector_signature) >= last_key)
00074 break;
00075
00076 const double actualDistance = (vector - i.value()).norm2();
00077 if (actualDistance < last_key)
00078 {
00079 closestVectors.take(last_key);
00080 closestVectors.insertMulti(actualDistance, i.value());
00081 last_key = (--(closestVectors.end())).key();
00082 }
00083 }
00084
00085
00086 for (QMap<double, QVVector>::const_iterator i = pivot + 1; i != constEnd(); ++i)
00087 {
00088 if (ABS(i.key() - vector_signature) >= last_key)
00089 break;
00090
00091 const double actualDistance = (vector - i.value()).norm2();
00092 if (actualDistance < last_key)
00093 {
00094 closestVectors.take(last_key);
00095 closestVectors.insertMulti(actualDistance, i.value());
00096 last_key = (--(closestVectors.end())).key();
00097 }
00098 }
00099
00100 return closestVectors.values();
00101 }