first commit
[synclust.git] / src / tests / t.neighbors.c
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 }