1 // This is rpl/rsdl/tests/test_bins_2d.cxx
2 #include <vector>
3 #include <iostream>
4 #include <algorithm>
5 #ifdef _MSC_VER
6 # include "vcl_msvc_warnings.h"
7 #endif
8
9 #include "vnl/vnl_vector_fixed.h"
10 #include "vnl/vnl_double_2.h"
11 #include "vnl/vnl_math.h"
12 #include "vnl/vnl_random.h"
13
14 #include "testlib/testlib_test.h"
15
16 #include <rsdl/rsdl_bins_2d.h>
17
test_bins_2d()18 static void test_bins_2d()
19 {
20 vnl_vector_fixed< double, 2 > min_pt, max_pt, bin_sizes;
21 min_pt[0] = 1.0; min_pt[1] = -2.5;
22 max_pt[0] = 75.0; max_pt[1] = 32;
23 bin_sizes[0] = 6; bin_sizes[1] = 4;
24
25 rsdl_bins_2d< double, int > bins( min_pt, max_pt, bin_sizes );
26 double dist_tol = 0.0001;
27 bins.set_distance_tolerance( dist_tol );
28 vnl_vector_fixed< double, 2 > pt( 12.5, 3 );
29 int value = 0;
30 bins.add_point( pt, value ); // should be 1, 0
31
32 pt[0] += dist_tol / 4;
33 pt[1] -= dist_tol / 4;
34 int changed_value = -5;
35 TEST("add point and change point", bins.change_point( pt, changed_value ), true);
36
37 int stored_value;
38 TEST("get value", bins.get_value( pt, stored_value ) &&
39 stored_value == changed_value, true);
40
41 vnl_vector_fixed< double, 2 > nearby( pt[0] + dist_tol, pt[1] - 2*dist_tol );
42
43 TEST("change nearby, but not close enough",
44 !bins.change_point( nearby, 22 ) &&
45 bins.get_value( pt, stored_value ) &&
46 stored_value == changed_value, true);
47
48 TEST("remove", bins.remove_point( pt ) &&
49 ! bins.get_value( pt, stored_value ), true);
50
51 pt[0] = 56.4; pt[1] = 31.0;
52 int added_value = 45;
53 bins.add_point( pt, added_value );
54 vnl_vector_fixed< double, 2 > pt2( 56.1, 30 );
55
56 TEST("remove -- not there", !bins.remove_point( pt2 ) &&
57 bins.get_value( pt, stored_value ) &&
58 stored_value == added_value, true);
59 TEST("remove -- different stored value", !bins.remove_point( pt, 30 ) &&
60 bins.get_value( pt, stored_value ) &&
61 stored_value == added_value, true);
62
63 TEST("remove with value", bins.remove_point( pt, added_value ) &&
64 !bins.get_value( pt, stored_value ), true);
65
66 pt[0] = 100; pt[1] = -30;
67 added_value = 24;
68 bins.add_point( pt, added_value );
69 TEST("adding point outside range", bins.get_value( pt, stored_value ) &&
70 stored_value == added_value, true);
71
72 pt[0] = -50; pt[1] = 77.7;
73 added_value = 13;
74 bins.add_point( pt, added_value );
75 TEST("adding point outside range", bins.get_value( pt, stored_value ) &&
76 stored_value == added_value, true);
77
78 // Generate a bunch of points:
79 constexpr int M = 60;
80 std::vector< vnl_vector_fixed< double, 2 > > points( M );
81 std::vector< int > indices( M );
82 vnl_random mz_rand;
83 bins.reset( min_pt, max_pt, bin_sizes );
84
85 for ( int i=0; i<M; ++i ) {
86 indices[ i ] = i;
87 points[ i ][0] = (max_pt[0] - min_pt[0]) * mz_rand.drand32() + min_pt[0];
88 points[ i ][1] = (max_pt[1] - min_pt[1]) * mz_rand.drand32() + min_pt[1];
89 bins.add_point( points[ i ], i );
90 }
91
92 // test "is_any_point_within_radius" and "points_with_radius"
93
94 constexpr int num_tests = 5;
95 for ( int t=0; t<num_tests; ++t ) {
96 vnl_vector_fixed< double, 2 > q;
97 q[0] = (max_pt[0] - min_pt[0]) * mz_rand.drand32() + min_pt[0];
98 q[1] = (max_pt[1] - min_pt[1]) * mz_rand.drand32() + min_pt[1];
99 double radius = (t+1) * bin_sizes[0] / 2; // increasing size, starting smallest
100
101 bool bin_answer = bins.is_any_point_within_radius( q, radius );
102
103 std::vector< int > all_close_indices;
104 for ( int i=0; i<M; ++i ) {
105 if ( vnl_vector_ssd( points[ i ], q ) < vnl_math::sqr( radius ) )
106 all_close_indices.push_back( i );
107 }
108
109 TEST("is_any_point_within_radius", bin_answer,
110 (!all_close_indices.empty()));
111
112 std::vector< int > bin_close_indices;
113 bins.points_within_radius( q, radius, bin_close_indices );
114 bool correct = all_close_indices.size() == bin_close_indices.size();
115 std::sort( all_close_indices.begin(), all_close_indices.end() );
116 std::sort( bin_close_indices.begin(), bin_close_indices.end() );
117
118 for ( unsigned int i=0; correct &&
119 i < std::min(all_close_indices.size(), bin_close_indices.size()); ++i )
120 correct = all_close_indices[ i ] == bin_close_indices[ i ];
121
122 TEST("points_within_radius", correct, true);
123 }
124
125 { //new test with bin size 5,5
126 vnl_double_2 a(0,0), b(100,100), c(5,5), d(4.9,0), e(8.8,0), f(1,0);
127 rsdl_bins_2d<double, int> bins(a,b,c);//min, max, size
128
129 bins.add_point(e, 1);
130 bins.add_point(f, 2);
131
132 std::vector<int> answer;
133 bins.n_nearest(d, 1, answer);
134
135 TEST("Second bin test bin size 5,5",
136 !answer.empty() && (answer[0] == 1 || answer[0] == 2), true);
137 }
138
139 {//same as new test with bin size 2,2
140 vnl_double_2 a(0,0), b(100,100), c(2,2), d(4.9,0), e(8.8,0), f(1,0);
141 rsdl_bins_2d<double, int> bins(a,b,c);//min, max, size
142
143 bins.add_point(e, 1);
144 bins.add_point(f, 2);
145
146 std::vector<int> answer;
147 bins.n_nearest(d, 1, answer);
148
149 TEST("Second bin test bin size 2,2",
150 !answer.empty() && (answer[0] == 1 || answer[0] == 2), true);
151 }
152 }
153
154 TESTMAIN(test_bins_2d);
155