Commit | Line | Data |
---|---|---|
15d1825d BA |
1 | #include "tests/helpers.h" |
2 | #include "sources/neighbors.h" | |
3 | #include <cgds/List.h> | |
4 | ||
5 | int** list2int(List** L, int n) | |
6 | { | |
7 | int** I = (int**)malloc(n*sizeof(int*)); | |
8 | for (int i=0; i<n; i++) | |
9 | { | |
10 | int listSize = list_size(L[i]); | |
11 | I[i] = (int*)malloc((1+listSize)*sizeof(int)); | |
12 | I[i][0] = listSize; | |
13 | ListIterator* iterJ = list_get_iterator(L[i]); | |
14 | for (int j=1; j<=listSize; j++) | |
15 | { | |
16 | listI_get(iterJ, I[i][j]); | |
17 | listI_move_next(iterJ); | |
18 | } | |
19 | listI_destroy(iterJ); | |
20 | } | |
21 | return I; | |
22 | } | |
23 | ||
24 | //10 lines 12 columns, only NA except on antidiagonal | |
25 | // ==> distances computed with coordinates only | |
26 | void test_neighbors1() | |
27 | { | |
28 | int n = 10, m=12; | |
29 | double M[120] = | |
30 | { | |
31 | NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,1.0,0.0,0.0, | |
32 | NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,1.0,NAN,1.0,1.0, | |
33 | NAN,NAN,NAN,NAN,NAN,NAN,NAN,1.0,NAN,NAN,2.0,2.0, | |
34 | NAN,NAN,NAN,NAN,NAN,NAN,1.0,NAN,NAN,NAN,3.0,3.0, | |
35 | NAN,NAN,NAN,NAN,NAN,1.0,NAN,NAN,NAN,NAN,4.0,4.0, | |
36 | NAN,NAN,NAN,NAN,1.0,NAN,NAN,NAN,NAN,NAN,5.0,5.0, | |
37 | NAN,NAN,NAN,1.0,NAN,NAN,NAN,NAN,NAN,NAN,6.0,6.0, | |
38 | NAN,NAN,1.0,NAN,NAN,NAN,NAN,NAN,NAN,NAN,7.0,7.0, | |
39 | NAN,1.0,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,8.0,8.0, | |
40 | 1.0,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,9.0,9.0 | |
41 | }; | |
42 | ||
43 | double alphas[4] = {-1.0, 0.0, 0.5, 1.0}; | |
44 | int k = 2; // no need for more | |
45 | for (int j=0; j<4; j++) | |
46 | { | |
47 | double alpha = alphas[j]; // no impact | |
48 | for (int gmode=0; gmode<4; gmode++) | |
49 | { | |
50 | List** L = getNeighbors_core(M, alpha, k, gmode, S_FALSE, n, m); | |
51 | int** NIix = list2int(L, n); | |
52 | for (int jj=0; jj<n; jj++) | |
53 | list_destroy(L[jj]); | |
54 | free(L); | |
55 | for (int jj=1; jj<n-1; jj++) | |
56 | { | |
57 | // interior points: 2 neighbors, below and above [except for gmode==1 and jj==2 or n-2] | |
58 | if (gmode==1 && (jj==2 || jj==n-3)) | |
59 | { | |
60 | ASSERT_TRUE( | |
61 | NIix[jj][0] == 3 && (NIix[jj][1] == jj-1 || NIix[jj][2] == jj-1 || NIix[jj][3] == jj-1)); | |
62 | ASSERT_TRUE( | |
63 | NIix[jj][0] == 3 && (NIix[jj][1] == jj+1 || NIix[jj][2] == jj+1 || NIix[jj][3] == jj+1)); | |
64 | if (jj==2) | |
65 | { | |
66 | ASSERT_TRUE( | |
67 | NIix[jj][0] == 3 && (NIix[jj][1] == jj-2 || NIix[jj][2] == jj-2 || NIix[jj][3] == jj-2)); | |
68 | } | |
69 | else if (jj==n-3) | |
70 | { | |
71 | ASSERT_TRUE( | |
72 | NIix[jj][0] == 3 && (NIix[jj][1] == jj+2 || NIix[jj][2] == jj+2 || NIix[jj][3] == jj+2)); | |
73 | } | |
74 | } | |
75 | else | |
76 | { | |
77 | // one neighb below, one neighb above | |
78 | ASSERT_TRUE( | |
79 | NIix[jj][0] == 2 && (NIix[jj][1] == jj-1 || NIix[jj][2] == jj-1)); | |
80 | ASSERT_TRUE( | |
81 | NIix[jj][0] == 2 && (NIix[jj][1] == jj+1 || NIix[jj][2] == jj+1)); | |
82 | } | |
83 | } | |
84 | // boundary points in mode 1 (augmented kNN) or 2 (normal kNN) also have 2 neighbors | |
85 | if (gmode==1 || gmode==2) | |
86 | { | |
87 | ASSERT_TRUE(NIix[0][0] == 2 && (NIix[0][1] == 1 || NIix[0][2] == 1)); | |
88 | ASSERT_TRUE(NIix[0][0] == 2 && (NIix[0][1] == 2 || NIix[0][2] == 2)); | |
89 | ASSERT_TRUE(NIix[n-1][0] == 2 && (NIix[n-1][1] == n-2 || NIix[n-1][2] == n-2)); | |
90 | ASSERT_TRUE(NIix[n-1][0] == 2 && (NIix[n-1][1] == n-3 || NIix[n-1][2] == n-3)); | |
91 | } | |
92 | else | |
93 | { | |
94 | // in mutual kNN or in 'by-quadrants' modes, they only have 1 neighbor. | |
95 | ASSERT_TRUE(NIix[0][0] == 1 && NIix[0][1] == 1); | |
96 | ASSERT_TRUE(NIix[n-1][0] == 1 && NIix[n-1][1] == n-2); | |
97 | } | |
98 | ||
99 | for (int i=0; i<n; i++) | |
100 | free(NIix[i]); | |
101 | free(NIix); | |
102 | } | |
103 | } | |
104 | } | |
105 | ||
106 | //10 lines, 6 columns, some NA's... | |
107 | void test_neighbors2() | |
108 | { | |
109 | int n = 6, m=10; | |
110 | double M[60] = | |
111 | { | |
112 | NAN,1.0,0.0,NAN,0.0,NAN,3.0,NAN,0.0,0.0, | |
113 | 1.0,2.0,0.0,NAN,NAN,0.0,2.0,3.0,1.0,1.0, | |
114 | 2.0,3.0,0.0,NAN,NAN,1.0,1.0,2.0,2.0,2.0, | |
115 | 3.0,NAN,0.0,NAN,1.0,NAN,NAN,1.0,3.0,3.0, | |
116 | 2.0,3.0,NAN,3.0,1.0,2.0,1.0,NAN,4.0,4.0, | |
117 | 1.0,0.0,NAN,2.0,NAN,1.0,3.0,NAN,5.0,5.0 | |
118 | }; | |
119 | ||
120 | List** L = getNeighbors_core(M, 0.5, 3, 2, S_FALSE, n, m); | |
121 | int** NIix = list2int(L, n); | |
122 | for (int j=0; j<n; j++) | |
123 | list_destroy(L[j]); | |
124 | free(L); | |
125 | ||
126 | // check neighbors of first row | |
127 | ASSERT_TRUE(NIix[0][0] == 3); | |
128 | for (int j=1; j<=3; j++) | |
129 | { | |
130 | ASSERT_TRUE(NIix[0][1] == j || | |
131 | NIix[0][2] == j || NIix[0][3] == j); | |
132 | } | |
133 | for (int i=0; i<n; i++) | |
134 | free(NIix[i]); | |
135 | free(NIix); | |
136 | ||
137 | L = getNeighbors_core(M, -1.0, 3, 2, S_FALSE, n, m); | |
138 | NIix = list2int(L, n); | |
139 | for (int j=0; j<n; j++) | |
140 | list_destroy(L[j]); | |
141 | free(L); | |
142 | ||
143 | // check neighbors of fifth row | |
144 | ASSERT_TRUE(NIix[4][0] == 3); | |
145 | for (int j=2; j<=5; j++) | |
146 | { | |
147 | if (j == 4) | |
148 | continue; //not self-neighbor | |
149 | ASSERT_TRUE(NIix[4][1] == j || | |
150 | NIix[4][2] == j || NIix[4][3] == j); | |
151 | } | |
152 | ||
153 | for (int i=0; i<n; i++) | |
154 | free(NIix[i]); | |
155 | free(NIix); | |
156 | } |