Coverage Report

Created: 2017-11-12 13:27

/home/liu/buildslave/linux-x64-runtests/build/test/unit/util.tests.c
Line
Count
Source
1
#include "ccv.h"
2
#include "case.h"
3
#include "ccv_case.h"
4
#include "3rdparty/dsfmt/dSFMT.h"
5
#include "3rdparty/sfmt/SFMT.h"
6
7
TEST_CASE("type size macro")
8
1
{
9
1
  
REQUIRE_EQ1
(CCV_GET_DATA_TYPE_SIZE(CCV_8U), 1, "CCV_8U should have size 1")
;1
10
1
  
REQUIRE_EQ1
(CCV_GET_DATA_TYPE_SIZE(CCV_32S), 4, "CCV_32S should have size 4")
;1
11
1
  
REQUIRE_EQ1
(CCV_GET_DATA_TYPE_SIZE(CCV_32F), 4, "CCV_32F should have size 4")
;1
12
1
  
REQUIRE_EQ1
(CCV_GET_DATA_TYPE_SIZE(CCV_64S), 8, "CCV_64S should have size 8")
;1
13
1
  
REQUIRE_EQ1
(CCV_GET_DATA_TYPE_SIZE(CCV_64F), 8, "CCV_64F should have size 8")
;1
14
1
}
15
16
TEST_CASE("dynamic array")
17
1
{
18
1
  ccv_array_t* array = ccv_array_new(4, 2, 0);
19
1
  int i;
20
1
  i = 1;
21
1
  ccv_array_push(array, &i);
22
1
  i = 2;
23
1
  ccv_array_push(array, &i);
24
1
  i = 3;
25
1
  ccv_array_push(array, &i);
26
1
  i = 4;
27
1
  ccv_array_push(array, &i);
28
1
  i = 5;
29
1
  ccv_array_push(array, &i);
30
1
  
REQUIRE_EQ1
(5, array->rnum, "should have 5 elements pushed to array")
;1
31
6
  for (i = 0; 
i < array->rnum6
;
i++5
)
32
5
    
REQUIRE_EQ5
(i + 1, ((int*)ccv_array_get(array, i))[0], "check element values in array")
;1
33
1
  ccv_array_clear(array);
34
1
  i = 3;
35
1
  ccv_array_push(array, &i);
36
1
  i = 4;
37
1
  ccv_array_push(array, &i);
38
1
  i = 5;
39
1
  ccv_array_push(array, &i);
40
1
  
REQUIRE_EQ1
(3, array->rnum, "should have 3 elements after clear")
;1
41
4
  for (i = 0; 
i < array->rnum4
;
i++3
)
42
3
    
REQUIRE_EQ3
(i + 3, ((int*)ccv_array_get(array, i))[0], "check element values in array after clear at index %d", i)
;1
43
1
  ccv_array_free(array);
44
1
}
45
46
TEST_CASE("array resize")
47
1
{
48
1
  ccv_array_t* array = ccv_array_new(4, 2, 0);
49
1
  int i;
50
1
  i = 1;
51
1
  ccv_array_push(array, &i);
52
1
  ccv_array_resize(array, 4);
53
1
  
REQUIRE_EQ1
(4, array->rnum, "should have 4 elements in array")
;1
54
1
  
REQUIRE_EQ1
(1, ((int*)ccv_array_get(array, 0))[0], "check element values in array")
;1
55
4
  for (i = 1; 
i < array->rnum4
;
i++3
)
56
3
    
REQUIRE_EQ3
(0, ((int*)ccv_array_get(array, i))[0], "check element values in array")
;1
57
1
  ccv_array_free(array);
58
1
}
59
60
int is_equal(const void* r1, const void* r2, void* data)
61
56
{
62
56
  int a = *(int*)r1;
63
56
  int b = *(int*)r2;
64
56
  return a == b;
65
56
}
66
67
TEST_CASE("group array with is_equal function")
68
1
{
69
1
  ccv_array_t* array = ccv_array_new(4, 2, 0);
70
1
  int i;
71
1
  i = 1;
72
1
  ccv_array_push(array, &i);
73
1
  i = 2;
74
1
  ccv_array_push(array, &i);
75
1
  i = 2;
76
1
  ccv_array_push(array, &i);
77
1
  i = 2;
78
1
  ccv_array_push(array, &i);
79
1
  i = 5;
80
1
  ccv_array_push(array, &i);
81
1
  i = 3;
82
1
  ccv_array_push(array, &i);
83
1
  i = 4;
84
1
  ccv_array_push(array, &i);
85
1
  i = 5;
86
1
  ccv_array_push(array, &i);
87
1
  ccv_array_t* idx = 0;
88
1
  ccv_array_group(array, &idx, is_equal, 0);
89
1
  
REQUIRE_EQ1
(((int*)ccv_array_get(idx, 1))[0], ((int*)ccv_array_get(idx, 2))[0], "element 2, 3 should in the same group")
;1
90
1
  
REQUIRE_EQ1
(((int*)ccv_array_get(idx, 2))[0], ((int*)ccv_array_get(idx, 3))[0], "element 3, 4 should in the same group")
;1
91
1
  
REQUIRE_EQ1
(((int*)ccv_array_get(idx, 4))[0], ((int*)ccv_array_get(idx, 7))[0], "element 4, 8 should in the same group")
;1
92
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 0))[0], ((int*)ccv_array_get(idx, 1))[0], "element 1, 2 should not in the same group")
;1
93
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 0))[0], ((int*)ccv_array_get(idx, 4))[0], "element 1, 5 should not in the same group")
;1
94
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 0))[0], ((int*)ccv_array_get(idx, 5))[0], "element 1, 6 should not in the same group")
;1
95
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 0))[0], ((int*)ccv_array_get(idx, 6))[0], "element 1, 7 should not in the same group")
;1
96
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 1))[0], ((int*)ccv_array_get(idx, 4))[0], "element 2, 5 should not in the same group")
;1
97
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 1))[0], ((int*)ccv_array_get(idx, 5))[0], "element 2, 6 should not in the same group")
;1
98
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 1))[0], ((int*)ccv_array_get(idx, 6))[0], "element 2, 7 should not in the same group")
;1
99
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 4))[0], ((int*)ccv_array_get(idx, 5))[0], "element 5, 6 should not in the same group")
;1
100
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 4))[0], ((int*)ccv_array_get(idx, 6))[0], "element 5, 7 should not in the same group")
;1
101
1
  
REQUIRE_NOT_EQ1
(((int*)ccv_array_get(idx, 5))[0], ((int*)ccv_array_get(idx, 6))[0], "element 6, 7 should not in the same group")
;1
102
1
  ccv_array_free(array);
103
1
  ccv_array_free(idx);
104
1
}
105
106
TEST_CASE("specific sparse matrix insertion")
107
1
{
108
1
  ccv_sparse_matrix_t* mat = ccv_sparse_matrix_new(1, 70, CCV_32S | CCV_C1, CCV_SPARSE_ROW_MAJOR, 0);
109
1
  const int k = 1;
110
1
  int idx[] = {26, 29, 30, 34, 35, 38, 39, 42, 43, 47, 48, 51, 52, 55, 56, 60, 61, 65, 66, 68, 69};
111
1
  int i;
112
22
  for (i = 0; 
i < sizeof(idx) / sizeof(int)22
;
i++21
)
113
21
    ccv_set_sparse_matrix_cell(mat, 0, idx[i], &k);
114
22
  for (i = 0; 
i < sizeof(idx) / sizeof(int)22
;
i++21
)
115
21
  {
116
21
    ccv_numeric_data_t cell = ccv_get_sparse_matrix_cell(mat, 0, idx[i]);
117
21
    
REQUIRE21
(cell.u8 != 0, "cell at (%d, %d) doesn't contain any valid value", 0, idx[i])
;21
118
21
    
REQUIRE_EQ21
(1, cell.i32[0], "cell at (%d, %d) doesn't match inserted value", 0, idx[i])
;21
119
21
  }
120
1
  ccv_matrix_free(mat);
121
1
}
122
123
TEST_CASE("sparse matrix basic insertion")
124
1
{
125
1
  ccv_sparse_matrix_t* mat = ccv_sparse_matrix_new(1000, 1000, CCV_32S | CCV_C1, CCV_SPARSE_ROW_MAJOR, 0);
126
1
  int i, j, k, n;
127
1
  k = 0;
128
1.00k
  for (i = 0; 
i < 10001.00k
;
i++1.00k
)
129
1.00M
    
for (j = 0; 1.00k
j < 10001.00M
;
j++1.00M
)
130
1.00M
    {
131
1.00M
      ccv_set_sparse_matrix_cell(mat, i, j, &k);
132
1.00M
      k++;
133
1.00M
    }
134
1
  
REQUIRE_EQ1
(1597, mat->size, "sparse matrix column size should be the prime number 1597")
;1
135
101
  for (n = 0; 
n < 100101
;
n++100
)
136
100
  {
137
100
    k = 0;
138
100k
    for (i = 0; 
i < 1000100k
;
i++100k
)
139
100M
      
for (j = 0; 100k
j < 1000100M
;
j++100M
)
140
100M
      {
141
100M
        ccv_numeric_data_t cell = ccv_get_sparse_matrix_cell(mat, i, j);
142
100M
        
REQUIRE100M
(cell.u8 != 0, "cell at (%d, %d) doesn't contain any valid value", i, j)
;100M
143
100M
        
REQUIRE_EQ100M
(k, cell.i32[0], "cell at (%d, %d) doesn't match inserted value", i, j)
;100M
144
100M
        k++;
145
100M
      }
146
100
  }
147
1
  ccv_matrix_free(mat);
148
1
}
149
150
TEST_CASE("compress sparse matrix")
151
1
{
152
1
  ccv_sparse_matrix_t* mat = ccv_sparse_matrix_new(3, 3, CCV_32F | CCV_C1, CCV_SPARSE_ROW_MAJOR, 0);
153
1
  float cell;
154
1
  cell = 1.0;
155
1
  ccv_set_sparse_matrix_cell(mat, 0, 0, &cell);
156
1
  cell = 2.0;
157
1
  ccv_set_sparse_matrix_cell(mat, 0, 2, &cell);
158
1
  cell = 3.0;
159
1
  ccv_set_sparse_matrix_cell(mat, 1, 2, &cell);
160
1
  cell = 4.0;
161
1
  ccv_set_sparse_matrix_cell(mat, 2, 0, &cell);
162
1
  cell = 5.0;
163
1
  ccv_set_sparse_matrix_cell(mat, 2, 1, &cell);
164
1
  cell = 6.0;
165
1
  ccv_set_sparse_matrix_cell(mat, 2, 2, &cell);
166
1
  ccv_compressed_sparse_matrix_t* csm = 0;
167
1
  ccv_compress_sparse_matrix(mat, &csm);
168
1
  float dm[6] = {1, 2, 3, 4, 5, 6};
169
1
  int di[6] = {0, 2, 2, 0, 1, 2};
170
1
  
REQUIRE_EQ1
(6, csm->nnz, "compress to non-zero factor of 6")
;1
171
1
  
REQUIRE_ARRAY_EQ_WITH_TOLERANCE1
(float, dm, csm->data.f32, 6, 1e-6, "actual element value should be the same")
;1
172
1
  
REQUIRE_ARRAY_EQ1
(int, di, csm->index, 6, "element index of CSR")
;1
173
1
  
REQUIRE_EQ1
(3, csm->rows, "compress should have the same number of rows (CSR)")
;1
174
1
  int df[4] = {0, 2, 3, 6};
175
1
  
REQUIRE_ARRAY_EQ1
(int, df, csm->offset, 4, "offset of leading element in each row")
;1
176
1
  ccv_sparse_matrix_t* smt = 0;
177
1
  ccv_decompress_sparse_matrix(csm, &smt);
178
1
  float m[3][3] = {{1, 0, 2}, {0, 0, 3}, {4, 5, 6}};
179
1
  int i, j;
180
4
  for (i = 0; 
i < 34
;
i++3
)
181
12
    
for (j = 0; 3
j < 312
;
j++9
)
182
9
    {
183
9
      ccv_numeric_data_t cell = ccv_get_sparse_matrix_cell(smt, i, j);
184
9
      
REQUIRE_EQ_WITH_TOLERANCE9
(m[i][j], (cell.u8 != 0) ? cell.f32[0] : 0, 1e-6, "should have the same matrix after decompressed at row %d, col %d", i, j)
;9
185
9
    }
186
1
  ccv_matrix_free(smt);
187
1
  ccv_matrix_free(mat);
188
1
  ccv_matrix_free(csm);
189
1
}
190
191
TEST_CASE("loop over sparse matrix")
192
1
{
193
1
  ccv_sparse_matrix_t* mat = ccv_sparse_matrix_new(1000, 1000, CCV_32F | CCV_C1, CCV_SPARSE_ROW_MAJOR, 0);
194
1
  ccv_dense_matrix_t* a = ccv_dense_matrix_new(1000, 1000, CCV_32F | CCV_C1, 0, 0);
195
1
  ccv_zero(a);
196
1
  ccv_dense_matrix_t* b = ccv_dense_matrix_new(1000, 1000, CCV_32F | CCV_C1, 0, 0);
197
1
  ccv_zero(b);
198
1
  dsfmt_t dsfmt;
199
1
  dsfmt_init_gen_rand(&dsfmt, 0xdead);
200
1
  sfmt_t sfmt;
201
1
  sfmt_init_gen_rand(&sfmt, 0xbeef);
202
1
  int i;
203
51
  for (i = 0; 
i < 5051
;
i++50
)
204
50
  {
205
50
    int x = sfmt_genrand_uint32(&sfmt) % 1000;
206
50
    int y = sfmt_genrand_uint32(&sfmt) % 1000;
207
50
    float v = dsfmt_genrand_close_open(&dsfmt);
208
50
    a->data.f32[y * 1000 + x] = v;
209
50
    ccv_set_sparse_matrix_cell(mat, y, x, &v);
210
50
  }
211
50
#define block(y, x, v) { b->data.f32[y * 1000 + x] = ((float*)v)[0]; }
212
50
  
CCV_SPARSE_FOREACH1
(mat,
block50
);
213
1
#undef block
214
1
  
REQUIRE_MATRIX_EQ1
(a, b, "matrix should be exactly equal when looped over the sparse one")1
;1
215
1
  ccv_matrix_free(mat);
216
1
  ccv_matrix_free(a);
217
1
  ccv_matrix_free(b);
218
1
}
219
220
TEST_CASE("loop over column major sparse matrix")
221
1
{
222
1
  ccv_sparse_matrix_t* mat = ccv_sparse_matrix_new(1000, 1000, CCV_32F | CCV_C1, CCV_SPARSE_COL_MAJOR, 0);
223
1
  ccv_dense_matrix_t* a = ccv_dense_matrix_new(1000, 1000, CCV_32F | CCV_C1, 0, 0);
224
1
  ccv_zero(a);
225
1
  ccv_dense_matrix_t* b = ccv_dense_matrix_new(1000, 1000, CCV_32F | CCV_C1, 0, 0);
226
1
  ccv_zero(b);
227
1
  dsfmt_t dsfmt;
228
1
  dsfmt_init_gen_rand(&dsfmt, 0xdead);
229
1
  sfmt_t sfmt;
230
1
  sfmt_init_gen_rand(&sfmt, 0xbeef);
231
1
  int i;
232
201
  for (i = 0; 
i < 200201
;
i++200
)
233
200
  {
234
200
    int x = sfmt_genrand_uint32(&sfmt) % 1000;
235
200
    int y = sfmt_genrand_uint32(&sfmt) % 1000;
236
200
    float v = dsfmt_genrand_close_open(&dsfmt);
237
200
    a->data.f32[y * 1000 + x] = v;
238
200
    ccv_set_sparse_matrix_cell(mat, y, x, &v);
239
200
  }
240
200
#define block(y, x, v) { b->data.f32[y * 1000 + x] = ((float*)v)[0]; }
241
200
  
CCV_SPARSE_FOREACH1
(mat,
block200
);
242
1
#undef block
243
1
  
REQUIRE_MATRIX_EQ1
(a, b, "matrix should be exactly equal when looped over the sparse one")1
;1
244
1
  ccv_matrix_free(mat);
245
1
  ccv_matrix_free(a);
246
1
  ccv_matrix_free(b);
247
1
}
248
249
TEST_CASE("loop over sparse matrix with dense vector")
250
1
{
251
1
  ccv_sparse_matrix_t* mat = ccv_sparse_matrix_new(1000, 1000, CCV_32F | CCV_C1 | CCV_DENSE_VECTOR, CCV_SPARSE_ROW_MAJOR, 0);
252
1
  ccv_dense_matrix_t* a = ccv_dense_matrix_new(1000, 1000, CCV_32F | CCV_C1, 0, 0);
253
1
  ccv_zero(a);
254
1
  ccv_dense_matrix_t* b = ccv_dense_matrix_new(1000, 1000, CCV_32F | CCV_C1, 0, 0);
255
1
  ccv_zero(b);
256
1
  dsfmt_t dsfmt;
257
1
  dsfmt_init_gen_rand(&dsfmt, 0xdead);
258
1
  sfmt_t sfmt;
259
1
  sfmt_init_gen_rand(&sfmt, 0xbeef);
260
1
  int i;
261
201
  for (i = 0; 
i < 200201
;
i++200
)
262
200
  {
263
200
    int x = sfmt_genrand_uint32(&sfmt) % 1000;
264
200
    int y = sfmt_genrand_uint32(&sfmt) % 1000;
265
200
    float v = dsfmt_genrand_close_open(&dsfmt);
266
200
    a->data.f32[y * 1000 + x] = v;
267
200
    ccv_set_sparse_matrix_cell(mat, y, x, &v);
268
200
  }
269
182k
#define block(y, x, v) { b->data.f32[y * 1000 + x] = ((float*)v)[0]; }
270
182k
  
CCV_SPARSE_FOREACH1
(mat,
block182k
);
271
1
#undef block
272
1
  
REQUIRE_MATRIX_EQ1
(a, b, "matrix should be exactly equal when looped over the sparse one")1
;1
273
1
  ccv_matrix_free(mat);
274
1
  ccv_matrix_free(a);
275
1
  ccv_matrix_free(b);
276
1
}
277
278
TEST_CASE("loop over sparse matrix vector")
279
1
{
280
1
  ccv_sparse_matrix_t* mat = ccv_sparse_matrix_new(1000, 1000, CCV_32F | CCV_C1, CCV_SPARSE_ROW_MAJOR, 0);
281
1
  ccv_dense_matrix_t* a = ccv_dense_matrix_new(1, 1000, CCV_32F | CCV_C1, 0, 0);
282
1
  ccv_zero(a);
283
1
  ccv_dense_matrix_t* b = ccv_dense_matrix_new(1, 1000, CCV_32F | CCV_C1, 0, 0);
284
1
  ccv_zero(b);
285
1
  dsfmt_t dsfmt;
286
1
  dsfmt_init_gen_rand(&dsfmt, 0xdead);
287
1
  sfmt_t sfmt;
288
1
  sfmt_init_gen_rand(&sfmt, 0xbeef);
289
1
  int i;
290
51
  for (i = 0; 
i < 5051
;
i++50
)
291
50
  {
292
50
    int x = sfmt_genrand_uint32(&sfmt) % 1000;
293
50
    float v = dsfmt_genrand_close_open(&dsfmt);
294
50
    a->data.f32[x] = v;
295
50
    ccv_set_sparse_matrix_cell(mat, 38, x, &v);
296
50
  }
297
1
  ccv_sparse_matrix_vector_t* vector = ccv_get_sparse_matrix_vector(mat, 38);
298
48
#define block(x, v) { b->data.f32[x] = ((float*)v)[0]; }
299
48
  
CCV_SPARSE_VECTOR_FOREACH1
(mat, vector,
block48
);
300
1
#undef block
301
1
  
REQUIRE_MATRIX_EQ1
(a, b, "matrix should be exactly equal when looped over the sparse one")1
;1
302
1
  ccv_matrix_free(mat);
303
1
  ccv_matrix_free(a);
304
1
  ccv_matrix_free(b);
305
1
}
306
307
TEST_CASE("loop over sparse matrix dense vector")
308
1
{
309
1
  ccv_sparse_matrix_t* mat = ccv_sparse_matrix_new(1000, 1000, CCV_32F | CCV_C1 | CCV_DENSE_VECTOR, CCV_SPARSE_ROW_MAJOR, 0);
310
1
  ccv_dense_matrix_t* a = ccv_dense_matrix_new(1, 1000, CCV_32F | CCV_C1, 0, 0);
311
1
  ccv_zero(a);
312
1
  ccv_dense_matrix_t* b = ccv_dense_matrix_new(1, 1000, CCV_32F | CCV_C1, 0, 0);
313
1
  ccv_zero(b);
314
1
  dsfmt_t dsfmt;
315
1
  dsfmt_init_gen_rand(&dsfmt, 0xdead);
316
1
  sfmt_t sfmt;
317
1
  sfmt_init_gen_rand(&sfmt, 0xbeef);
318
1
  int i;
319
201
  for (i = 0; 
i < 200201
;
i++200
)
320
200
  {
321
200
    int x = sfmt_genrand_uint32(&sfmt) % 1000;
322
200
    float v = dsfmt_genrand_close_open(&dsfmt);
323
200
    a->data.f32[x] = v;
324
200
    ccv_set_sparse_matrix_cell(mat, 38, x, &v);
325
200
  }
326
1
  ccv_sparse_matrix_vector_t* vector = ccv_get_sparse_matrix_vector(mat, 38);
327
1.00k
#define block(x, v) { b->data.f32[x] = ((float*)v)[0]; }
328
1.00k
  
CCV_SPARSE_VECTOR_FOREACH1
(mat, vector,
block1.00k
);
329
1
#undef block
330
1
  
REQUIRE_MATRIX_EQ1
(a, b, "matrix should be exactly equal when looped over the sparse one")1
;1
331
1
  ccv_matrix_free(mat);
332
1
  ccv_matrix_free(a);
333
1
  ccv_matrix_free(b);
334
1
}
335
336
TEST_CASE("matrix slice")
337
1
{
338
1
  ccv_dense_matrix_t* image = 0;
339
1
  ccv_read("../../samples/chessbox.png", &image, CCV_IO_ANY_FILE);
340
1
  ccv_dense_matrix_t* b = 0;
341
1
  ccv_slice(image, (ccv_matrix_t**)&b, 0, 33, 41, 111, 91);
342
1
  
REQUIRE_MATRIX_FILE_EQ1
(b, "data/chessbox.slice.bin", "should have data/chessbox.png sliced at (33, 41) with 111 x 91");1
343
1
  ccv_matrix_free(image);
344
1
  ccv_matrix_free(b);
345
1
}
346
347
TEST_CASE("matrix flatten")
348
1
{
349
1
  ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(2, 2, CCV_8U | CCV_C2, 0, 0);
350
1
  dmt->data.u8[0] = 200;
351
1
  dmt->data.u8[1] = 100;
352
1
  dmt->data.u8[2] = 150;
353
1
  dmt->data.u8[3] = 50;
354
1
  dmt->data.u8[4] = 25;
355
1
  dmt->data.u8[5] = 20;
356
1
  dmt->data.u8[6] = 200;
357
1
  dmt->data.u8[7] = 250;
358
1
  ccv_dense_matrix_t* result = 0;
359
1
  ccv_flatten(dmt, (ccv_matrix_t**)&result, 0, 0);
360
1
  ccv_matrix_free(dmt);
361
1
  int rf[4] = {300, 200, 45, 450};
362
1
  
REQUIRE_EQ1
(CCV_GET_CHANNEL(result->type), CCV_C1, "flatten matrix should have only one channel")
;1
363
1
  
REQUIRE_ARRAY_EQ1
(int, result->data.i32, rf, 4, "matrix flatten should have same value as reference array")
;1
364
1
  ccv_matrix_free(result);
365
1
}
366
367
TEST_CASE("matrix reshape")
368
1
{
369
1
  ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(2, 4, CCV_32S | CCV_C1, 0, 0);
370
1
  dmt->data.i32[0] = 200;
371
1
  dmt->data.i32[1] = 100;
372
1
  dmt->data.i32[2] = 150;
373
1
  dmt->data.i32[3] = 50;
374
1
  dmt->data.i32[4] = 25;
375
1
  dmt->data.i32[5] = 20;
376
1
  dmt->data.i32[6] = 200;
377
1
  dmt->data.i32[7] = 250;
378
1
  ccv_dense_matrix_t sub = ccv_reshape(dmt, 0, 2, 2, 2);
379
1
  ccv_dense_matrix_t* a = ccv_dense_matrix_new(2, 2, CCV_32S | CCV_C1, 0, 0);
380
1
  a->data.i32[0] = 100;
381
1
  a->data.i32[1] = 100;
382
1
  a->data.i32[2] = 100;
383
1
  a->data.i32[3] = 100;
384
1
  ccv_subtract(a, &sub, (ccv_matrix_t**)&a, 0);
385
1
  int rf[4] = {-50, 50, -100, -150};
386
1
  
REQUIRE_ARRAY_EQ1
(int, a->data.i32, rf, 4, "matrix subtract a reshaped matrix should have same value as reference array")
;1
387
1
  ccv_matrix_free(a);
388
1
  ccv_matrix_free(dmt);
389
1
}
390
391
TEST_CASE("matrix border")
392
1
{
393
1
  ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32F | CCV_C1, 0, 0);
394
1
  dmt->data.f32[0] = 2.0;
395
1
  ccv_dense_matrix_t* result = 0;
396
1
  ccv_margin_t margin = ccv_margin(2, 3, 1, 2);
397
1
  ccv_border(dmt, (ccv_matrix_t**)&result, 0, margin);
398
1
  ccv_matrix_free(dmt);
399
1
  float rf[24] = {
400
1
    0, 0, 0, 0,
401
1
    0, 0, 0, 0,
402
1
    0, 0, 0, 0,
403
1
    0, 0, 2, 0,
404
1
    0, 0, 0, 0,
405
1
    0, 0, 0, 0,
406
1
  };
407
1
  
REQUIRE_EQ1
(margin.top + margin.bottom + 1, result->rows, "bordered matrix should have margin.top + margin.bottom + 1 rows")
;1
408
1
  
REQUIRE_EQ1
(margin.left + margin.right + 1, result->cols, "bordered matrix should have margin.left + margin.right + 1 cols")
;1
409
1
  
REQUIRE_ARRAY_EQ_WITH_TOLERANCE1
(float, result->data.f32, rf, 24, 1e-5, "matrix border should have same value as reference array")
;1
410
1
  ccv_matrix_free(result);
411
1
}
412
413
TEST_CASE("half precision and float-point conversion")
414
1
{
415
1
  uint16_t* h = (uint16_t*)ccmalloc(sizeof(uint16_t) * 0x10000);
416
1
  float* f = (float*)ccmalloc(sizeof(float) * 0x10000);
417
1
  uint16_t* b = (uint16_t*)ccmalloc(sizeof(uint16_t) * 0x10000);
418
1
  float* c = (float*)ccmalloc(sizeof(float) * 0x10000);
419
1
  int i;
420
65.5k
  for (i = 0; 
i < 0x1000065.5k
;
i++65.5k
)
421
65.5k
    h[i] = i;
422
1
  ccv_half_precision_to_float(h, f, 0x10000);
423
1
  ccv_float_to_half_precision(f, b, 0x10000);
424
1
  
REQUIRE_ARRAY_EQ1
(uint16_t, h, b, 0x10000, "half precision convert to float and then convert back should match exactly")
;1
425
2.05k
  for (i = 0; 
i <= 20482.05k
;
i++2.04k
)
426
2.04k
    f[i] = i;
427
1
  ccv_float_to_half_precision(f, h, 2049);
428
1
  ccv_half_precision_to_float(h, c, 2049);
429
1
  
REQUIRE_ARRAY_EQ_WITH_TOLERANCE1
(float, f, c, 2049, 1e-5, "0-2048 integer to half precision and convert back should match exactly")
;1
430
4.09k
  for (i = 4097; 
i <= 81924.09k
;
i++4.09k
)
431
4.09k
    f[i - 4097] = i;
432
1
  ccv_float_to_half_precision(f, h, 8192 - 4097 + 1);
433
1
  ccv_half_precision_to_float(h, c, 8192 - 4097 + 1);
434
1
  
REQUIRE_ARRAY_EQ_WITH_TOLERANCE1
(float, f, c, 8192 - 4097 + 1, 4 + 1e-5, "4097-8192 integer to half precision and convert back should round to multiple of 4")
;1
435
1
  ccfree(h);
436
1
  ccfree(f);
437
1
  ccfree(b);
438
1
  ccfree(c);
439
1
}
440
441
#include "case_main.h"