Skip to content

Commit 6b4610e

Browse files
committed
added unit sphere radius for high dimensions
added tests, too. this should fix #21
1 parent a8afc3b commit 6b4610e

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

RTree.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,16 @@ RTREE_QUAL::RTree()
491491

492492
m_root = AllocNode();
493493
m_root->m_level = 0;
494-
m_unitSphereVolume = (ELEMTYPEREAL)UNIT_SPHERE_VOLUMES[NUMDIMS];
494+
495+
if (NUMDIMS < 21)
496+
{
497+
m_unitSphereVolume = (ELEMTYPEREAL)UNIT_SPHERE_VOLUMES[NUMDIMS];
498+
} else {
499+
// Stirling's approximation, applicable to high dimensions
500+
// https://en.wikipedia.org/wiki/Volume_of_an_n-ball#Approximation_for_high_dimensions
501+
m_unitSphereVolume = (ELEMTYPEREAL)(1.0 / std::sqrt(NUMDIMS * M_PI) *
502+
std::pow(2 * M_PI * M_E / NUMDIMS, NUMDIMS / 2.0));
503+
}
495504
}
496505

497506

tests/CMakeLists.txt

+11
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,22 @@ target_link_libraries(
6262
GTest::gmock_main
6363
)
6464

65+
add_executable(
66+
highDim
67+
highDim.cpp
68+
)
69+
target_link_libraries(
70+
highDim
71+
GTest::gtest_main
72+
GTest::gmock_main
73+
)
74+
6575
include(GoogleTest)
6676
gtest_discover_tests(basics)
6777
gtest_discover_tests(memory)
6878
gtest_discover_tests(badData)
6979
gtest_discover_tests(largeData)
7080
gtest_discover_tests(treeList)
7181
gtest_discover_tests(nearestNeighbour)
82+
gtest_discover_tests(highDim)
7283

tests/highDim.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include "../RTree.h"
2+
#include "util.hpp"
3+
#include <gmock/gmock.h>
4+
#include <gtest/gtest-matchers.h>
5+
#include <gtest/gtest.h>
6+
#include <vector>
7+
#include <random>
8+
9+
std::random_device rd;
10+
std::mt19937 gen(rd());
11+
std::uniform_real_distribution<> range(0, 1);
12+
13+
class RectND
14+
{
15+
public:
16+
RectND(int n)
17+
{
18+
for (int i = 0; i < n; i++)
19+
{
20+
m_min.push_back(range(gen));
21+
m_max.push_back(range(gen));
22+
}
23+
}
24+
25+
std::vector<float> m_min, m_max;
26+
};
27+
28+
using namespace ::testing;
29+
30+
TEST(HighDim, HighDim) {
31+
constexpr uint NDIM = 100;
32+
typedef RTree<int, float, NDIM> MyTree;
33+
MyTree tree;
34+
35+
int nrects = 1000;
36+
37+
for (int i = 0; i < nrects; i++) {
38+
const RectND rect(NDIM);
39+
tree.Insert(rect.m_min.data(), rect.m_max.data(), i);
40+
}
41+
42+
MyTree::Iterator it;
43+
int counter = 0;
44+
for (tree.GetFirst(it); !tree.IsNull(it); tree.GetNext(it)) {
45+
counter++;
46+
}
47+
48+
ASSERT_EQ(counter, nrects);
49+
}

0 commit comments

Comments
 (0)