* Bugs 16337 16455 fixed: [..,..,ku] = unique(..) implemented
[scilab.git] / scilab / modules / elementary_functions / tests / unit_tests / unique.tst
1 // =============================================================================
2 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 // Copyright (C) 2018-2020 - Samuel Gougeon
4 //
5 //  This file is distributed under the same license as the Scilab package.
6 // =============================================================================
7 // unit test of unique()
8 //
9 // <-- CLI SHELL MODE -->
10 // <-- NO CHECK REF -->
11 // <-- ENGLISH IMPOSED -->
12
13 // =====================
14 // Checking output sizes
15 // =====================
16 objects = list([], 7, 1:5, (1:5)', [1 3 5 ; 2 4 6], matrix(1:12,[2 3 2]));
17 for o = objects
18     [u,ki,ko,nb] = unique(o);
19     n = length(o);
20     if o==[], su = [0 0]; else su = [n 1]; end
21     if isrow(o), su = [1 n]; end
22     assert_checkequal(size(u), su);
23     assert_checkequal(size(ki), su);
24     assert_checkequal(size(ko), size(o));
25     assert_checkequal(size(nb), size(ki));
26 end
27 objects($) = null(); // Removing hypermat (excluded from "r" and "c" options)
28 for o = objects
29     [u,ki,ko,nb] = unique(o, "r");
30     [nr, nc] = size(o);
31     if o==[], su = [0 0]; else su = [nr 1]; end
32     assert_checkequal(size(u),  size(o));
33     assert_checkequal(size(ki), su);
34     assert_checkequal(size(ko), su);
35     assert_checkequal(size(nb), size(ki));
36
37     [u,ki,ko,nb] = unique(o, "c");
38     [nr, nc] = size(o);
39     if o==[], su = [0 0]; else su = [1 nc]; end
40     assert_checkequal(size(u),  size(o));
41     assert_checkequal(size(ki), su);
42     assert_checkequal(size(ko), su);
43     assert_checkequal(size(nb), size(ki));
44 end
45
46
47 // ====================
48 // With decimal numbers
49 // ====================
50 // -----
51 // EMPTY
52 // -----
53 // By element
54 [u,ki,ko,nb] = unique([]);
55 assert_checkequal(u, []);
56 assert_checkequal(ki, []);
57 assert_checkequal(ko, []);
58 assert_checkequal(nb, []);
59 // "r"
60 [u,ki,ko,nb] = unique([], "r");
61 assert_checkequal(u, []);
62 assert_checkequal(ki, []);
63 assert_checkequal(ko, []);
64 assert_checkequal(nb, []);
65 // "c"
66 [u,ki,ko,nb] = unique([], "c");
67 assert_checkequal(u, []);
68 assert_checkequal(ki, []);
69 assert_checkequal(ko, []);
70 assert_checkequal(nb, []);
71
72 // ---
73 // ROW
74 // ---
75 x = [1 3 %nan 3 %inf 4 0 %nan 4 1];
76
77 // By elements
78 [u, ki, ko, nb] = unique(x);
79 assert_checkequal(u, [0  1  3  4  %inf  %nan  %nan]);
80 assert_checkequal(ki, [7  1  2  6  5  3  8]);
81 assert_checkequal(x(ki), u);
82 assert_checkequal(ko, [2  3  6  3  5  4  1  7  4  2]);
83 assert_checkequal(u(ko), x);
84 assert_checkequal(nb, [1  2  2  2  1  1  1]);
85 // "r"
86 [u,ki,ko,nb] = unique(x, "r");
87 assert_checkequal(u, x);
88 assert_checkequal(ki, 1);
89 assert_checkequal(x(ki,:), u);
90 assert_checkequal(ko, 1);
91 assert_checkequal(u(ko,:), x);
92 assert_checkequal(nb, 1);
93 // "c"
94 [u,ki,ko,nb] = unique(x, "c");
95 assert_checkequal(u, [0  1  3  4  %inf  %nan  %nan]);
96 assert_checkequal(ki, [7  1  2  6  5  3  8]);
97 assert_checkequal(x(:,ki), u);
98 assert_checkequal(ko, [2  3  6  3  5  4  1  7  4  2]);
99 assert_checkequal(u(:,ko), x);
100 assert_checkequal(nb, [1  2  2  2  1  1  1]);
101
102 // ------
103 // COLUMN
104 // ------
105 x = x';
106 // By elements
107 [u, ki, ko, nb] = unique(x);
108 assert_checkequal(u, [0  1  3  4  %inf  %nan  %nan]');
109 assert_checkequal(ki, [7  1  2  6  5  3  8]');
110 assert_checkequal(x(ki), u);
111 assert_checkequal(ko, [2  3  6  3  5  4  1  7  4  2]');
112 assert_checkequal(u(ko), x);
113 assert_checkequal(nb, [1  2  2  2  1  1  1]');
114 // "r"
115 [u,ki,ko,nb] = unique(x, "r");
116 assert_checkequal(u, [0  1  3  4  %inf  %nan  %nan]');
117 assert_checkequal(ki, [7  1  2  6  5  3  8]');
118 assert_checkequal(x(ki,:), u);
119 assert_checkequal(ko, [2  3  6  3  5  4  1  7  4  2]');
120 assert_checkequal(u(ko,:), x);
121 assert_checkequal(nb, [1  2  2  2  1  1  1]');
122 // "c"
123 [u,ki,ko,nb] = unique(x, "c");
124 assert_checkequal(u, x);
125 assert_checkequal(ki, 1);
126 assert_checkequal(x(:,ki), u);
127 assert_checkequal(ko, 1);
128 assert_checkequal(u(:,ko), x);
129 assert_checkequal(nb, 1);
130
131 // ------
132 // MATRIX
133 // ------
134 x = [ 2  0  2  2  2  0  0  0  2  0  0  2  2  1  0  1
135       1  2  2  2  1  0  2  2  0  0  1  0  1  1  0  0
136     ];
137 u = unique(x);
138 assert_checkequal(u, [0 1 2]');
139 [u,ki,ko,nb] = unique(x);
140 assert_checkequal(u, [0 1 2]');
141 assert_checkequal(ki, [3 2 1]');
142 assert_checkequal(ko, x+1);
143 assert_checkequal(u(ko), x);
144 assert_checkequal(nb,[13 7 12]');
145 // "c"
146 u = unique(x, "c");
147 uxc = [ 0  0  0  1  1  2  2  2
148         0  1  2  0  1  0  1  2
149       ];
150 assert_checkequal(u, uxc);
151 [u,ki,ko,nb] = unique(x, "c");
152 assert_checkequal(u, uxc);
153 assert_checkequal(ki, [6  11  2  16  14  9  1  3]);
154 assert_checkequal(x(:,ki), u);
155 assert_checkequal(ko, [7 3 8 8 7 1 3 3 6 1 2 6 7 5 1 4]);
156 assert_checkequal(u(:,ko), x);
157 assert_checkequal(nb, [3  1  3  1  1  2  3  2]);
158 // "r"
159 x = x';
160 u = unique(x, "r");
161 uxc = [ 0  0  0  1  1  2  2  2
162         0  1  2  0  1  0  1  2
163       ]';
164 assert_checkequal(u, uxc);
165 [u,ki,ko,nb] = unique(x, "r");
166 assert_checkequal(u, uxc);
167 assert_checkequal(ki, [6  11  2  16  14  9  1  3]');
168 assert_checkequal(x(ki,:), u);
169 assert_checkequal(ko, [7 3 8 8 7 1 3 3 6 1 2 6 7 5 1 4]');
170 assert_checkequal(u(ko,:), x);
171 assert_checkequal(nb, [3  1  3  1  1  2  3  2]');
172
173 // -----------
174 // HYPERMATRIX
175 // -----------
176 x = cat(3,[2 0 %nan 1 ; 2 1 0 2], [%inf 2 1 2 ; 1 0 %nan 2]);
177 [u,ki,ko,nb] = unique(x);
178 assert_checkequal(u, [0 1 2 %inf %nan %nan]');
179 assert_checkequal(ki, [3  4  1  9  5  14]');
180 assert_checkequal(u(ko), x);
181 assert_checkequal(nb, [3  4  6  1  1  1]');
182 msg = "unique: Argument #2: ''r'' not allowed for an hypermatrix.";
183 assert_checkerror("unique(x, ""r"")", msg);
184 msg = "unique: Argument #2: ''c'' not allowed for an hypermatrix.";
185 assert_checkerror("unique(x, ""c"")", msg);
186
187 // ---------
188 // keepOrder
189 // ---------
190 x = [ 2  0  2  2  2  0  0  0  2  0  0  2  2  1  0  1
191       1  2  2  2  1  0  2  2  0  0  1  0  1  1  0  0
192     ];
193 [u,ki,ko,nb] = unique(x, "keepOrder");
194 assert_checkequal(u, [2 1 0]');
195 assert_checkequal(ki, [1 2 3]');
196 assert_checkequal(x(ki), u);
197 assert_checkequal(u(ko), x);
198 assert_checkequal(nb,[12 7 13]');
199
200 uxc = [2  0  2  0  2  0  1  1
201        1  2  2  0  0  1  1  0
202       ];
203 // "r"
204 [u,ki,ko,nb] = unique(x', "r", "keepOrder");
205 assert_checkequal(u, uxc');
206 assert_checkequal(ki, [1  2  3  6  9  11 14 16]');
207 assert_checkequal(x'(ki,:), u);
208 assert_checkequal(u(ko,:), x');
209 assert_checkequal(nb, [3  3  2  3  2  1  1  1 ]');
210 // "c"
211 [u,ki,ko,nb] = unique(x, "c", "keepOrder");
212 assert_checkequal(u, uxc);
213 assert_checkequal(ki, [1  2  3  6  9  11 14 16]);
214 assert_checkequal(x(:,ki), u);
215 assert_checkequal(u(:,ko), x);
216 assert_checkequal(nb, [3  3  2  3  2  1  1  1 ]);
217
218
219 // --------------
220 // More with Nans
221 // --------------
222 Nan = %nan; Inf = %inf;
223 x = [Nan  Nan  Inf  Nan  0  Inf  Inf  Nan  Inf  Nan
224      Inf  0    Nan  0    0  0    Nan  Nan  0    0
225     ];
226 u = unique(x);
227 assert_checkequal(u, [0 Inf Nan*ones(1,8)]');
228 [u,ki,ko,nb] = unique(x);
229 assert_checkequal(u, [0 Inf Nan*ones(1,8)]');
230 assert_checkequal(ki, [4 2 1 3 6 7 14 15 16 19]');
231 assert_checkequal(x(ki), u);
232 assert_checkequal(u(ko), x);
233 assert_checkequal(nb,[7 5 1 1 1 1 1  1  1  1]');
234 //
235 u = unique(x, "c");
236 uxc = [0  Inf  Inf  Inf  Nan  Nan  Nan  Nan  Nan
237        0  0    Nan  Nan  0    0    0    Inf  Nan
238       ];
239 assert_checkequal(u, uxc);
240 [u,ki,ko,nb] = unique(x, "c");
241 assert_checkequal(u, uxc);
242 assert_checkequal(ki, [5  6  3  7  2  4 10  1  8]);
243 assert_checkequal(x(:,ki), u);
244 assert_checkequal(u(:,ko), x);
245 assert_checkequal(nb,[1  2  1  1  1  1  1  1  1]);
246
247 u = unique(x', "r");
248 assert_checkequal(u, uxc');
249 [u,ki,ko,nb] = unique(x', "r");
250 assert_checkequal(u, uxc');
251 assert_checkequal(ki, [5  6  3  7  2  4 10  1  8]');
252 assert_checkequal(x'(ki,:), u);
253 assert_checkequal(u(ko,:), x');
254 assert_checkequal(nb,[1  2  1  1  1  1  1  1  1]');
255
256 // With Nans & "uniqueNan" option
257 // ------------------------------
258 [u,ki,ko,nb] = unique(x, "uniqueNan");
259 assert_checkequal(u, [0 Inf Nan]');
260 assert_checkequal(ki, [4 2 1]');
261 assert_checkequal(x(ki), u);
262 assert_checkequal(u(ko), x);
263 assert_checkequal(nb,[7 5 8]');
264 //
265 uxc = [0  Inf  Inf  Nan  Nan  Nan
266        0  0    Nan  0    Inf  Nan
267       ];
268 [u,ki,ko,nb] = unique(x, "c", "uniqueNan");
269 assert_checkequal(u, uxc);
270 assert_checkequal(ki, [5  6  3  2  1  8]);
271 assert_checkequal(x(:,ki), u);
272 assert_checkequal(u(:,ko), x);
273 assert_checkequal(nb,[1  2  2  3  1  1]);
274
275 [u,ki,ko,nb] = unique(x', "r", "uniqueNan");
276 assert_checkequal(u, uxc');
277 assert_checkequal(ki, [5  6  3  2  1  8]');
278 assert_checkequal(x'(ki,:), u);
279 assert_checkequal(u(ko,:), x');
280 assert_checkequal(nb,[1  2  2  3  1  1]');
281
282 // With Nans & "uniqueNan" & "keepOrder" options
283 // ---------------------------------------------
284 [u,ki,ko,nb] = unique(x, "uniqueNan", "keepOrder");
285 assert_checkequal(u, [Nan Inf 0]');
286 assert_checkequal(ki, [1 2 4]');
287 assert_checkequal(x(ki), u);
288 assert_checkequal(u(ko), x);
289 assert_checkequal(nb,[8 5 7]');
290 //
291 uxc = [Nan  Nan  Inf  0  Inf  Nan
292        Inf  0    Nan  0  0    Nan
293       ];
294 //x = [Nan  Nan  Inf  Nan  0  Inf  Inf  Nan  Inf  Nan
295 //     Inf  0    Nan  0    0  0    Nan  Nan  0    0
296 [u,ki,ko,nb] = unique(x, "c", "uniqueNan", "keepOrder");
297 assert_checkequal(u, uxc);
298 assert_checkequal(ki, [1  2  3  5  6  8]);
299 assert_checkequal(x(:,ki), u);
300 assert_checkequal(u(:,ko), x);
301 assert_checkequal(nb,[1  3  2  1  2  1]);
302
303 [u,ki,ko,nb] = unique(x', "r", "uniqueNan", "keepOrder");
304 assert_checkequal(u, uxc');
305 assert_checkequal(ki, [1  2  3  5  6  8]');
306 assert_checkequal(x'(ki,:), u);
307 assert_checkequal(u(ko,:), x');
308 assert_checkequal(nb,[1  3  2  1  2  1]');
309
310 // =====================
311 // With encoded integers
312 // =====================
313 x = int8([-3 0 2 0 -3
314           -3 0 2 0 -3
315           -3 2 0 2 -3
316          ]);
317 u = unique(x);
318 assert_checkequal(u, int8([-3 0 2])');
319 [u,ki,ko,nb] = unique(x);
320 assert_checkequal(u, int8([-3 0 2])');
321 assert_checkequal(ki, [1 4 6]');
322 assert_checkequal(x(ki), u);
323 assert_checkequal(u(ko), x);
324 assert_checkequal(nb,[6 5 4]');
325
326 u = unique(x, "r");
327 assert_checkequal(u, int8([-3 0 2 0 -3 ; -3 2 0 2 -3]));
328 [u,ki,ko,nb] = unique(x, "r");
329 assert_checkequal(u, int8([-3 0 2 0 -3 ; -3 2 0 2 -3]));
330 assert_checkequal(ki, [1;3]);
331 assert_checkequal(x(ki,:), u);
332 assert_checkequal(u(ko,:), x);
333 assert_checkequal(nb,[2;1]);
334
335 u = unique(x, "c");
336 assert_checkequal(u, int8([-3 0 2 ; -3 0 2; -3 2 0]));
337 [u,ki,ko,nb] = unique(x, "c");
338 assert_checkequal(u, int8([-3 0 2 ; -3 0 2; -3 2 0]));
339 assert_checkequal(ki, [1 2 3]);
340 assert_checkequal(x(:,ki), u);
341 assert_checkequal(u(:,ko), x);
342 assert_checkequal(nb,[2 2 1]);
343
344 // =============
345 // With booleans
346 // =============
347 x = [%F %T %F %F %F %T %T
348      %F %T %T %F %T %F %F ];
349 [u,ki,ko,nb] = unique(x);
350 assert_checkequal(u, [%F ; %T]);
351 assert_checkequal(ki, [1;3]);
352 assert_checkequal(x(ki), u);
353 assert_checkequal(u(ko), x);
354 assert_checkequal(nb,[8;6]);
355
356 [u,ki,ko,nb] = unique(x, "c");
357 assert_checkequal(u, [%F %F %T %T ; %F %T %F %T]);
358 assert_checkequal(ki, [1 3 6 2]);
359 assert_checkequal(x(:,ki), u);
360 assert_checkequal(u(:,ko), x);
361 assert_checkequal(nb,[2 2 2 1]);
362
363
364
365 // ====================
366 // With complex numbers
367 // ====================
368 i = %i;
369 x = [1-i, 3+2*i, 1+i, 3-2*i, 3+2*i, 3-i, 1-i];
370 assert_checkequal(unique(x), [1-i, 1+i, 3-i, 3-2*i, 3+2*i]);
371 [u,ki,ko,nb] = unique(x);
372 assert_checkequal(u, [1-i, 1+i, 3-i, 3-2*i, 3+2*i]);
373 assert_checkequal(ki, [1  3  6  4  2]);
374 assert_checkequal(x(ki), u);
375 assert_checkequal(u(ko), x);
376 assert_checkequal(nb,[2  1  1  1  2]);
377
378 c = [x($:-1:1) ; x ; x($:-1:1) ; 1:7 ; x];
379 u = unique(c, "r");
380 assert_checkequal(u, c([4 1 2],:));
381 [u,ki,ko,nb] = unique(c, "r");
382 assert_checkequal(u, c([4 1 2],:));
383 assert_checkequal(ki, [4 1 2]');
384 assert_checkequal(c(ki,:), u);
385 assert_checkequal(u(ko,:), c);
386 assert_checkequal(nb,[1 2 2]');
387
388 c = c.';
389 u = unique(c, "c");
390 kref = [4 1 2];
391 assert_checkequal(u, c(:,kref));
392 [u,ki,ko,nb] = unique(c, "c");
393 assert_checkequal(u, c(:,kref));
394 assert_checkequal(ki, kref);
395 assert_checkequal(c(:,ki), u);
396 assert_checkequal(u(:,ko), c);
397 assert_checkequal(nb,[1 2 2]);
398
399 // ---------
400 // keepOrder
401 // ---------
402 // ROW
403 [u,ki,ko,nb] = unique(x, "keepOrder");
404 assert_checkequal(u, [1-i, 3+2*i, 1+i, 3-2*i, 3-i]);
405 assert_checkequal(ki, [1  2  3  4  6]);
406 assert_checkequal(x(ki), u);
407 assert_checkequal(u(ko), x);
408 assert_checkequal(nb,[2  2 1  1  1 ]);
409
410 c = [x($:-1:1) ; x ; x($:-1:1) ; 1:7 ; x];
411 kref = [1 2 4];
412 [u,ki,ko,nb] = unique(c, "r", "keepOrder");
413 assert_checkequal(u, c(kref,:));
414 assert_checkequal(ki, kref');
415 assert_checkequal(c(ki,:), u);
416 assert_checkequal(u(ko,:), c);
417 assert_checkequal(nb,[2 2 1]');
418
419 c = c.';
420 [u,ki,ko,nb] = unique(c, "c", "keepOrder");
421 assert_checkequal(u, c(:,kref));
422 assert_checkequal(ki, kref);
423 assert_checkequal(c(:,ki), u);
424 assert_checkequal(u(:,ko), c);
425 assert_checkequal(nb, [2 2 1]);
426
427 // ==============
428 // With some text
429 // ==============
430 t = ["AB" "BA" "BA" "BA" "AB" "BA" "AB" "AB" "BB" "AA" "AB" "BA" "BA" "BA" "AA"
431      "AA" "AA" "AB" "AA" "BB" "BB" "BB" "BA" "AB" "AB" "BB" "BB" "AB" "AB" "AA"
432     ];
433 u = unique(t);
434 assert_checkequal(u, ["AA" "AB" "BA" "BB"]');
435 [u,ki,ko,nb] = unique(t);
436 assert_checkequal(u, ["AA" "AB" "BA" "BB"]');
437 assert_checkequal(ki, [2 1 3 10]');
438 assert_checkequal(t(ki), u);
439 assert_checkequal(u(ko), t);
440 assert_checkequal(nb,[6 10 8 6]');
441
442 utc = ["AA"  "AA"  "AB"  "AB"  "AB"  "BA"  "BA"  "BA"  "BB"
443        "AA"  "AB"  "AA"  "BA"  "BB"  "AA"  "AB"  "BB"  "AB"
444       ];
445 u = unique(t, "c");
446 assert_checkequal(u, utc);
447 [u,ki,ko,nb] = unique(t, "c");
448 assert_checkequal(u, utc);
449 assert_checkequal(ki, [15 10 1 8 5 2 3 6 9]);
450 assert_checkequal(t(:,ki), u);
451 assert_checkequal(u(:,ko), t);
452 assert_checkequal(nb,[1  1  1 1 3 2 3 2 1]);
453
454 u = unique(t', "r");
455 assert_checkequal(u, utc');
456 [u,ki,ko,nb] = unique(t', "r");
457 assert_checkequal(u, utc');
458 assert_checkequal(ki, [15 10 1 8 5 2 3 6 9]');
459 assert_checkequal(t'(ki,:), u);
460 assert_checkequal(u(ko,:), t');
461 assert_checkequal(nb,[1  1  1 1 3 2 3 2 1]');
462
463 // keepOrder
464 // ---------
465 [u,ki,ko,nb] = unique(t, "keepOrder");
466 assert_checkequal(u, ["AB" "AA" "BA" "BB"]');
467 assert_checkequal(ki, [1 2 3 10]');
468 assert_checkequal(t(ki), u);
469 assert_checkequal(u(ko), t);
470 assert_checkequal(nb,[10 6 8 6]');
471
472 utc = ["AB"  "BA"  "BA"  "AB"  "BA"  "AB"  "BB"  "AA"  "AA"
473        "AA"  "AA"  "AB"  "BB"  "BB"  "BA"  "AB"  "AB"  "AA"
474       ];
475 [u,ki,ko,nb] = unique(t, "c", "keepOrder");
476 assert_checkequal(u, utc);
477 assert_checkequal(ki, [1 2 3 5 6 8 9 10 15]);
478 assert_checkequal(t(:,ki), u);
479 assert_checkequal(u(:,ko), t);
480 assert_checkequal(nb,[1 2 3 3 2 1 1 1  1 ]);
481
482 [u,ki,ko,nb] = unique(t', "r", "keepOrder");
483 assert_checkequal(u, utc');
484 assert_checkequal(ki, [1 2 3 5 6 8 9 10 15]');
485 assert_checkequal(t'(ki,:), u);
486 assert_checkequal(u(ko,:), t');
487 assert_checkequal(nb,[1 2 3 3 2 1 1 1  1 ]');