From f40db8b264db3347ce25827ad04286cef78102c2 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 17 Sep 2011 18:41:36 +0000 Subject: [PATCH] maxdist algorithm added [SVN r74438] --- .../index/algorithms/detail/diff_abs.hpp | 27 +++++ .../extensions/index/algorithms/maxdist.hpp | 69 ++++++++++++ .../index/algorithms/minmaxdist.hpp | 71 ++---------- tests/additional_sizes_and_times.cpp | 106 ++++++++++++++++-- 4 files changed, 203 insertions(+), 70 deletions(-) create mode 100644 include/boost/geometry/extensions/index/algorithms/detail/diff_abs.hpp create mode 100644 include/boost/geometry/extensions/index/algorithms/maxdist.hpp diff --git a/include/boost/geometry/extensions/index/algorithms/detail/diff_abs.hpp b/include/boost/geometry/extensions/index/algorithms/detail/diff_abs.hpp new file mode 100644 index 000000000..4c89b31c1 --- /dev/null +++ b/include/boost/geometry/extensions/index/algorithms/detail/diff_abs.hpp @@ -0,0 +1,27 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// +// Boost.Index - Abs of difference +// +// Copyright 2011 Adam Wulkiewicz. +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_DETAIL_DIFF_ABS_HPP +#define BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_DETAIL_DIFF_ABS_HPP + +namespace boost { namespace geometry { namespace index { + +namespace detail { + +template +inline T diff_abs(T const& v1, T const& v2) +{ + return v1 < v2 ? v2 - v1 : v1 - v2; +} + +} // namespace detail + +}}} // namespace boost::geometry::index + +#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_DETAIL_DIFF_ABS_HPP diff --git a/include/boost/geometry/extensions/index/algorithms/maxdist.hpp b/include/boost/geometry/extensions/index/algorithms/maxdist.hpp new file mode 100644 index 000000000..1aa7a9b94 --- /dev/null +++ b/include/boost/geometry/extensions/index/algorithms/maxdist.hpp @@ -0,0 +1,69 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// +// Boost.Index - maxdist used in R-tree k nearest neighbors query +// +// Copyright 2011 Adam Wulkiewicz. +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_MAXDIST_HPP +#define BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_MAXDIST_HPP + +#include +#include + +namespace boost { namespace geometry { namespace index { + +namespace detail { + +// minmaxdist component + +struct maxdist_tag {}; + +template < + typename Point, + typename BoxIndexable, + size_t DimensionIndex> +struct sum_for_indexable_dimension +{ + typedef typename geometry::default_distance_result::type result_type; + + inline static result_type apply(Point const& pt, BoxIndexable const& i) + { + typedef typename index::traits::coordinate_type::type point_coord_t; + typedef typename index::traits::coordinate_type::type indexable_coord_t; + + point_coord_t pt_c = geometry::get(pt); + indexable_coord_t ind_c_min = geometry::get(i); + indexable_coord_t ind_c_max = geometry::get(i); + + result_type further_diff = 0; + + if ( (ind_c_min + ind_c_max) / 2 <= pt_c ) + further_diff = pt_c - ind_c_min; + else + further_diff = detail::diff_abs(pt_c, ind_c_max); // unsigned values protection + + return further_diff * further_diff; + } +}; + +} // namespace detail + +template +typename geometry::default_distance_result::type +maxdist(Point const& pt, Indexable const& i) +{ + return sum_for_indexable< + Point, + Indexable, + typename index::traits::tag::type, + maxdist_tag, + index::traits::dimension::value + >::apply(pt, i); +} + +}}} // namespace boost::geometry::index + +#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_MAXDIST_HPP diff --git a/include/boost/geometry/extensions/index/algorithms/minmaxdist.hpp b/include/boost/geometry/extensions/index/algorithms/minmaxdist.hpp index 4ce994250..815ceefab 100644 --- a/include/boost/geometry/extensions/index/algorithms/minmaxdist.hpp +++ b/include/boost/geometry/extensions/index/algorithms/minmaxdist.hpp @@ -10,67 +10,16 @@ #ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_MINMAXDIST_HPP #define BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_MINMAXDIST_HPP +#include #include #include +#include + namespace boost { namespace geometry { namespace index { namespace detail { -// awulkiew - use if unsigned values may be used as coordinates -template -inline T diff_abs(T const& v1, T const& v2) -{ - return v1 < v2 ? v2 - v1 : v1 - v2; -} - -// minmaxdist component - -struct minmaxdist_comp_tag {}; - -template < - typename Point, - typename BoxIndexable, - size_t DimensionIndex> -struct sum_for_indexable_dimension -{ - typedef typename geometry::default_distance_result::type result_type; - - inline static result_type apply(Point const& pt, BoxIndexable const& i) - { - typedef typename index::traits::coordinate_type::type point_coord_t; - typedef typename index::traits::coordinate_type::type indexable_coord_t; - - point_coord_t pt_c = geometry::get(pt); - indexable_coord_t ind_c_min = geometry::get(i); - indexable_coord_t ind_c_max = geometry::get(i); - - result_type further_diff = 0; - - if ( (ind_c_min + ind_c_max) / 2 <= pt_c ) - further_diff = pt_c - ind_c_min; - else - further_diff = diff_abs(pt_c, ind_c_max); // unsigned values protection - - return further_diff * further_diff; - } -}; - -template -typename geometry::default_distance_result::type -minmaxdist_comp(Point const& pt, Indexable const& i) -{ - return sum_for_indexable< - Point, - Indexable, - typename index::traits::tag::type, - minmaxdist_comp_tag, - index::traits::dimension::value - >::apply(pt, i); -} - -// minmaxdist - struct minmaxdist_tag {}; template < @@ -81,7 +30,7 @@ struct smallest_for_indexable_dimension::type result_type; - inline static result_type apply(Point const& pt, BoxIndexable const& i, result_type const& comp) + inline static result_type apply(Point const& pt, BoxIndexable const& i, result_type const& maxd) { typedef typename index::traits::coordinate_type::type point_coord_t; typedef typename index::traits::coordinate_type::type indexable_coord_t; @@ -97,17 +46,17 @@ struct smallest_for_indexable_dimension inline static result_type apply(Point const& pt, Indexable const& i) { - result_type comp = minmaxdist_comp(pt, i); + result_type maxd = maxdist(pt, i); return smallest_for_indexable< Point, @@ -146,7 +95,7 @@ struct minmaxdist_impl box_tag, minmaxdist_tag, index::traits::dimension::value - >::apply(pt, i, comp); + >::apply(pt, i, maxd); } }; diff --git a/tests/additional_sizes_and_times.cpp b/tests/additional_sizes_and_times.cpp index 2d5061155..82f1736cc 100644 --- a/tests/additional_sizes_and_times.cpp +++ b/tests/additional_sizes_and_times.cpp @@ -114,7 +114,8 @@ int main() // elements inserting test { - std::cout << "inserting time test...\n"; + std::cout << "rtree inserting time test... (" + << values_count << ")\n"; tim.restart(); for (size_t i = 0 ; i < values_count ; ++i ) { @@ -127,6 +128,24 @@ int main() std::cout << "time: " << tim.elapsed() << "s\n"; } + std::vector< std::pair > v; + + // elements inserting test + { + std::cout << "vector inserting time test... (" + << values_count << ")\n"; + tim.restart(); + for (size_t i = 0 ; i < values_count ; ++i ) + { + float x = coords[i].first; + float y = coords[i].second; + B b(P(x - 0.5f, y - 0.5f), P(x + 0.5f, y + 0.5f)); + + v.push_back(std::make_pair(b, i)); + } + std::cout << "time: " << tim.elapsed() << "s\n"; + } + // check if ( bgi::are_boxes_ok(t) ) std::cout << "BOXES OK\n"; @@ -139,7 +158,8 @@ int main() // searching test { - std::cout << "query(intersects(B)) searching time test...\n"; + std::cout << "query(intersects(B)) searching time test... (" + << queries_count << ")\n"; tim.restart(); size_t temp = 0; for (size_t i = 0 ; i < queries_count ; ++i ) @@ -156,7 +176,8 @@ int main() // searching test { - std::cout << "query(B) searching time test...\n"; + std::cout << "query(B) searching time test... (" + << queries_count << ")\n"; tim.restart(); size_t temp = 0; for (size_t i = 0 ; i < queries_count ; ++i ) @@ -173,7 +194,36 @@ int main() // searching test { - std::cout << "nearest searching time test...\n"; + std::cout << "vector searching time test... (" + << queries_count / 1000 << ")\n"; + tim.restart(); + size_t temp = 0; + for (size_t i = 0 ; i < queries_count / 1000 ; ++i ) + { + float x = coords[i].first; + float y = coords[i].second; + std::deque< std::pair > result; + for ( std::vector< std::pair >::const_iterator it = v.begin(); + it != v.end() ; + ++it ) + { + if ( bg::intersects( + it->first, + B(P(x - 10, y - 10), P(x + 10, y + 10)) + ) + ) + result.push_back(*it); + } + temp += result.size(); + } + std::cout << "time: " << tim.elapsed() << "s\n"; + std::cout << "found: " << temp << "\n"; + } + + // searching test + { + std::cout << "nearest searching time test... (" + << queries_count / 10 << ")\n"; tim.restart(); size_t temp = 0; for (size_t i = 0 ; i < queries_count / 10 ; ++i ) @@ -189,7 +239,8 @@ int main() // searching test { - std::cout << "nearest searching time test...\n"; + std::cout << "nearest 5 searching time test... (" + << queries_count / 10 << ")\n"; tim.restart(); size_t temp = 0; for (size_t i = 0 ; i < queries_count / 10 ; ++i ) @@ -203,9 +254,43 @@ int main() std::cout << "found: " << temp << "\n"; } + // searching test + { + std::cout << "vector nearest searching time test... (" + << queries_count / 1000 << ")\n"; + tim.restart(); + size_t temp = 0; + for (size_t i = 0 ; i < queries_count / 1000 ; ++i ) + { + typedef bg::default_distance_result::type distance_type; + + float x = coords[i].first + 100; + float y = coords[i].second + 100; + std::pair result; + distance_type dist = std::numeric_limits::max(); + + for ( std::vector< std::pair >::const_iterator it = v.begin(); + it != v.end(); + ++it ) + { + distance_type cd = bgi::mindist(P(x, y), it->first); + + if ( cd < dist ) + { + result = *it; + dist = cd; + } + } + temp += dist < std::numeric_limits::max() ? 1 : 0; + } + std::cout << "time: " << tim.elapsed() << "s\n"; + std::cout << "found: " << temp << "\n"; + } + // elements removing test { - std::cout << "removing time test...\n"; + std::cout << "removing time test... (" + << remove_count << ")\n"; tim.restart(); for (size_t i = 0 ; i < remove_count ; ++i ) { @@ -230,7 +315,8 @@ int main() // searching test { - std::cout << "searching time test...\n"; + std::cout << "searching time test... (" + << queries_count << ")\n"; tim.restart(); size_t temp = 0; for (size_t i = 0 ; i < queries_count ; ++i ) @@ -247,7 +333,8 @@ int main() // inserting test { - std::cout << "inserting time test...\n"; + std::cout << "inserting time test... (" + << remove_count << ")\n"; tim.restart(); for (size_t i = 0 ; i < remove_count ; ++i ) { @@ -272,7 +359,8 @@ int main() // searching test { - std::cout << "searching time test...\n"; + std::cout << "searching time test... (" + << queries_count << ")\n"; tim.restart(); size_t temp = 0; for (size_t i = 0 ; i < queries_count ; ++i )