From 170cffad9742bbc12acd7ed522b797c111fdd6db Mon Sep 17 00:00:00 2001 From: Davis King Date: Fri, 18 Jan 2013 22:10:42 -0500 Subject: [PATCH] Added make_sparse_vector_inplace() --- dlib/svm/sparse_vector.h | 57 +++++++++++++++++++++++++++++++ dlib/svm/sparse_vector_abstract.h | 18 ++++++++++ dlib/test/sparse_vector.cpp | 30 ++++++++++++++++ 3 files changed, 105 insertions(+) diff --git a/dlib/svm/sparse_vector.h b/dlib/svm/sparse_vector.h index 2fa055094..79825f7be 100644 --- a/dlib/svm/sparse_vector.h +++ b/dlib/svm/sparse_vector.h @@ -908,6 +908,63 @@ namespace dlib return T(temp.begin(), temp.end()); } +// ---------------------------------------------------------------------------------------- + + template < + typename T + > + void make_sparse_vector_inplace( + T& vect + ) + { + vect = make_sparse_vector(vect); + } + +// ---------------------------------------------------------------------------------------- + + template < + typename T, + typename U, + typename alloc + > + void make_sparse_vector_inplace ( + std::vector,alloc>& vect + ) + { + if (vect.size() > 0) + { + std::sort(vect.begin(), vect.end()); + + // merge duplicates + for (unsigned long i = 1; i < vect.size(); ++i) + { + // if we found a duplicate + if (vect[i-1].first == vect[i].first) + { + // now start collapsing and merging the vector + unsigned long j = i-1; + for (unsigned long k = i; k < vect.size(); ++k) + { + if (vect[j].first == vect[k].first) + { + vect[j].second += vect[k].second; + } + else + { + ++j; + vect[j] = vect[k]; + } + } + + + // we removed elements when we merged so we need to adjust the size. + vect.resize(j+1); + return; + } + } + } + } + // ---------------------------------------------------------------------------------------- template diff --git a/dlib/svm/sparse_vector_abstract.h b/dlib/svm/sparse_vector_abstract.h index 5679d80aa..d4785cdf1 100644 --- a/dlib/svm/sparse_vector_abstract.h +++ b/dlib/svm/sparse_vector_abstract.h @@ -512,6 +512,24 @@ namespace dlib will still logically represent the same vector). !*/ +// ---------------------------------------------------------------------------------------- + + template < + typename T + > + void make_sparse_vector_inplace( + T& vect + ); + /*! + requires + - v is an unsorted sparse vector + ensures + - vect == make_sparse_vector(vect) + - This function is just an optimized version of make_sparse_vector(), in + particular, when T is a std::vector> type it is much more + efficient. + !*/ + // ---------------------------------------------------------------------------------------- template < diff --git a/dlib/test/sparse_vector.cpp b/dlib/test/sparse_vector.cpp index 0f124a56e..9c92cb53a 100644 --- a/dlib/test/sparse_vector.cpp +++ b/dlib/test/sparse_vector.cpp @@ -110,6 +110,34 @@ namespace DLIB_TEST(max(abs(r1-r2)) < 1e-15); } +// ---------------------------------------------------------------------------------------- + + void test_make_sparse_vector_inplace() + { + std::vector > vect; + vect.push_back(make_pair(4,1)); + vect.push_back(make_pair(0,1)); + vect.push_back(make_pair(4,1)); + vect.push_back(make_pair(3,1)); + vect.push_back(make_pair(8,1)); + vect.push_back(make_pair(8,1)); + vect.push_back(make_pair(8,1)); + vect.push_back(make_pair(8,1)); + + make_sparse_vector_inplace(vect); + + DLIB_TEST(vect.size() == 4); + DLIB_TEST(vect[0].first == 0); + DLIB_TEST(vect[1].first == 3); + DLIB_TEST(vect[2].first == 4); + DLIB_TEST(vect[3].first == 8); + + DLIB_TEST(vect[0].second == 1); + DLIB_TEST(vect[1].second == 1); + DLIB_TEST(vect[2].second == 2); + DLIB_TEST(vect[3].second == 4); + } + // ---------------------------------------------------------------------------------------- class sparse_vector_tester : public tester @@ -129,6 +157,8 @@ namespace void perform_test ( ) { + test_make_sparse_vector_inplace(); + std::map v; v[4] = 8; v[2] = -4;