test_spatial_hash.cpp
Go to the documentation of this file.
1 // Copyright 2022-2023 Ekumen, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <gtest/gtest.h>
16 
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 #include <tuple>
21 #include <vector>
22 
23 #include <range/v3/range/conversion.hpp>
24 #include <range/v3/view/cartesian_product.hpp>
25 #include <range/v3/view/iota.hpp>
26 #include <range/v3/view/transform.hpp>
27 
29 
30 namespace {
31 
32 TEST(SpatialHash, Round) {
33  using Tuple = std::tuple<double, double>;
34  constexpr std::array kClusteringResolution{1., 1.};
35  auto hasher = beluga::spatial_hash<Tuple>{kClusteringResolution};
36  auto hash1 = hasher(std::make_tuple(10.3, 5.0));
37  auto hash2 = hasher(std::make_tuple(10.0, 5.0));
38  auto hash3 = hasher(std::make_tuple(10.0, 5.3));
39  auto hash4 = hasher(std::make_tuple(10.1, 5.1));
40  EXPECT_EQ(hash1, hash2);
41  EXPECT_EQ(hash2, hash3);
42  EXPECT_EQ(hash3, hash4);
43  auto hash5 = hasher(std::make_tuple(9.1, 5.1));
44  auto hash6 = hasher(std::make_tuple(10.1, 4.1));
45  EXPECT_NE(hash1, hash5);
46  EXPECT_NE(hash1, hash6);
47 }
48 
49 TEST(SpatialHash, Resolution) {
50  using Tuple = std::tuple<double, double>;
51  constexpr std::array kClusteringResolution{0.1, 0.1};
52  auto hasher = beluga::spatial_hash<Tuple>{kClusteringResolution};
53 
54  auto hash1 = hasher(std::make_tuple(10.3, 5.13));
55  auto hash2 = hasher(std::make_tuple(10.33, 5.14));
56  EXPECT_EQ(hash1, hash2);
57  auto hash3 = hasher(std::make_tuple(10.0, 5.0));
58  EXPECT_NE(hash1, hash3);
59 }
60 
61 TEST(SpatialHash, Negative) {
62  using Tuple = std::tuple<double, double>;
63  constexpr std::array kClusteringResolution{0.1, 0.1};
64  auto hasher = beluga::spatial_hash<Tuple>{kClusteringResolution};
65  auto hash1 = hasher(std::make_tuple(-10.3, -2.13));
66  auto hash2 = hasher(std::make_tuple(-10.27, -2.14));
67  EXPECT_EQ(hash1, hash2);
68  auto hash3 = hasher(std::make_tuple(-10.0, -2.0));
69  EXPECT_NE(hash1, hash3);
70 }
71 
72 TEST(SpatialHash, NoCollisions) {
73  using Tuple = std::tuple<double, double, double>;
74  constexpr int kLimit = 100;
75  constexpr std::array kClusteringResolution{1., 1., 1.};
76  auto hasher = beluga::spatial_hash<Tuple>{kClusteringResolution};
77 
78  // Brute-force search for collisions.
79  // With kLimit = 100 and a 3-element tuple, we test 8'120'601 combinations.
80  auto hashes = ranges::views::cartesian_product(
81  ranges::views::closed_iota(-kLimit, kLimit), ranges::views::closed_iota(-kLimit, kLimit),
82  ranges::views::closed_iota(-kLimit, kLimit)) |
83  ranges::views::transform([hasher](const auto& tuple) {
84  return hasher(std::make_tuple(
85  static_cast<double>(std::get<0>(tuple)), static_cast<double>(std::get<1>(tuple)),
86  static_cast<double>(std::get<2>(tuple))));
87  }) |
88  ranges::to<std::vector>;
89 
90  std::sort(std::begin(hashes), std::end(hashes));
91  auto it = std::adjacent_find(std::begin(hashes), std::end(hashes));
92  const bool has_duplicates = it != std::end(hashes);
93  ASSERT_FALSE(has_duplicates);
94 }
95 
96 TEST(SpatialHash, Array) {
97  using Array = std::array<double, 3>;
98  using Tuple = std::tuple<double, double, double>;
99  constexpr std::array kClusteringResolution{1., 1., 1.};
100  auto array_hasher = beluga::spatial_hash<Array>{kClusteringResolution};
101  auto tuple_hasher = beluga::spatial_hash<Tuple>{kClusteringResolution};
102 
103  auto hash1 = array_hasher({1., 2., 3.});
104  auto hash2 = tuple_hasher({1., 2., 3.});
105  EXPECT_EQ(hash1, hash2);
106 }
107 
108 TEST(SpatialHash, NonPeriodicityCheck1) {
109  using Array = std::array<double, 8>;
110  constexpr std::array kClusteringResolution{1., 1., 1., 1., 1., 1., 1., 1.};
111 
112  auto uut = beluga::spatial_hash<Array>{kClusteringResolution};
113 
114  auto hash0 = uut({0., 0., 0., 0., 0., 0., 0., 0.});
115  auto hash1 = uut({64., 0., 0., 0., 0., 0., 0., 0.});
116  auto hash2 = uut({128., 0., 0., 0., 0., 0., 0., 0.});
117  auto hash3 = uut({192., 0., 0., 0., 0., 0., 0., 0.});
118  auto hash4 = uut({256., 0., 0., 0., 0., 0., 0., 0.});
119 
120  EXPECT_NE(hash0, hash1);
121  EXPECT_NE(hash0, hash2);
122  EXPECT_NE(hash0, hash3);
123  EXPECT_NE(hash0, hash4);
124 }
125 
126 TEST(SpatialHash, NonPeriodicityCheck2) {
127  using Array = std::array<double, 8>;
128  constexpr std::array kClusteringResolution{1., 1., 1., 1., 1., 1., 1., 1.};
129  constexpr double kStep = 2.0;
130 
131  auto uut = beluga::spatial_hash<Array>{kClusteringResolution};
132 
133  auto ref_hash = uut({0., 0., 0., 0., 0., 0., 0., 0.});
134 
135  for (double n = kStep; n < 1024.; n += kStep) {
136  auto hash0 = uut({n, 0., 0., 0., 0., 0., 0., 0.});
137  auto hash1 = uut({0., n, 0., 0., 0., 0., 0., 0.});
138  auto hash2 = uut({0., 0., n, 0., 0., 0., 0., 0.});
139  auto hash3 = uut({0., 0., 0., n, 0., 0., 0., 0.});
140  auto hash4 = uut({0., 0., 0., 0., n, 0., 0., 0.});
141  auto hash5 = uut({0., 0., 0., 0., 0., n, 0., 0.});
142  auto hash6 = uut({0., 0., 0., 0., 0., 0., n, 0.});
143  auto hash7 = uut({0., 0., 0., 0., 0., 0., 0., n});
144  EXPECT_NE(ref_hash, hash0);
145  EXPECT_NE(ref_hash, hash1);
146  EXPECT_NE(ref_hash, hash2);
147  EXPECT_NE(ref_hash, hash3);
148  EXPECT_NE(ref_hash, hash4);
149  EXPECT_NE(ref_hash, hash5);
150  EXPECT_NE(ref_hash, hash6);
151  EXPECT_NE(ref_hash, hash7);
152  }
153 }
154 
155 } // namespace
beluga::spatial_hash
Callable class, allowing to calculate the hash of a particle state.
Definition: spatial_hash.hpp:100
spatial_hash.hpp
Implementation of a spatial hash for N dimensional states.
beluga::TEST
TEST(Bresenham, MultiPassGuarantee)
Definition: test_bresenham.cpp:27


beluga
Author(s):
autogenerated on Tue Jul 16 2024 02:59:53