vectorfind() upgrade: short needle, wildcard, hypermats, %nan
[scilab.git] / scilab / modules / elementary_functions / tests / unit_tests / vectorfind.tst
1 // =============================================================================
2 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 // Copyright (C) 2017 - Samuel GOUGEON
4 //
5 // This file is hereby licensed under the terms of the GNU GPL v2.0,
6 // pursuant to article 5.3.4 of the CeCILL v.2.1.
7 // This file was originally licensed under the terms of the CeCILL v2.1,
8 // and continues to be available under such terms.
9 // For more information, see the COPYING file which you should have received
10 // along with this program.
11 // =============================================================================
12 //
13 // <-- CLI SHELL MODE -->
14 // <-- NO CHECK REF -->
15 //
16 // <-- Unit test of vectorfind() -->
17
18 m = [
19   1  0  0  0  1  0  1  0  1  0  0  1  1  1  1
20   0  0  1  0  0  1  0  1  0  0  0  0  0  0  0
21   0  1  1  1  0  0  1  1  1  0  1  1  0  0  1
22   0  0  1  0  1  0  1  0  1  0  0  0  0  0  1
23   ];
24 H = [1 0 0 1 2 0 0 0 1 0 2 1 2 2 1 0 1 2
25      2 2 1 0 0 2 1 0 2 0 1 2 1 0 0 1 0 0];
26 H = matrix(H, [2 3 3 2])
27 // --> H = matrix(H, [2 3 3 2])
28 //  H  =
29 // (:,:,1,1)
30 //    1   0   0
31 //    2   2   1
32 // (:,:,2,1)
33 //    1   2   0
34 //    0   0   2
35 // (:,:,3,1)
36 //    0   0   1
37 //    1   0   2
38 //
39 // (:,:,1,2)
40 //    0   2   1
41 //    0   1   2
42 // (:,:,2,2)
43 //    2   2   1
44 //    1   0   0
45 // (:,:,3,2)
46 //    0   1   2
47 //    1   0   0
48
49 // ==================
50 // CHECKING ARGUMENTS
51 // ==================
52 // Number of arguments
53 assert_checkfalse(execstr("vectorfind()","errcatch")==0);
54 assert_checkfalse(execstr("vectorfind(m,[1 0 1 0],""c"",2,"""",%t)","errcatch")==0);
55 assert_checktrue (execstr("a=vectorfind(m,[1 0 1 0],""c"")","errcatch")==0);
56 assert_checktrue (execstr("[a,b]=vectorfind(m,[1 0 1 0],""c"")","errcatch")==0);
57 assert_checkfalse(execstr("[a,b,c]=vectorfind(m,[1 0 1 0],""c"")","errcatch")==0);
58
59 // Needle's orientation does not matter:
60 assert_checkequal(vectorfind(m, [0 0 1 0], "c"), [2 4 11]);
61 assert_checkequal(vectorfind(m, [0 0 1 0]', "c"), [2 4 11]);
62 assert_checkequal(vectorfind(m, cat(3, 0,0,1,0), "c"), [2 4 11]);
63 assert_checkequal(vectorfind(H, [0 1], "c"), [3 7 16]);
64 assert_checkequal(vectorfind(H, [0 1]', "c"), [3 7 16]);
65 assert_checkequal(vectorfind(H, cat(3, 0,1), "c"), [3 7 16]);
66
67 // Empty needle gets empty result:
68 assert_checkequal(vectorfind(m, []), []);
69 assert_checkequal(vectorfind(m, [], "c"), []);
70 assert_checkequal(vectorfind(H, []), []);
71 assert_checkequal(vectorfind(H, [], "c"), []);
72 assert_checkequal(vectorfind(H, [], 3), []);
73 assert_checkequal(vectorfind(H, [], 4), []);
74
75 // Too long needles get empty results:
76 assert_checkequal(vectorfind(m, 1:5, "c"), []);   // too tall v
77 assert_checkequal(vectorfind(m, 1:16, "r"), []);  // too long v
78 assert_checkequal(vectorfind(H, [0 1 0 2], "r"), []);
79 assert_checkequal(vectorfind(H, [0 1 0], "c"), []); // size = 2
80 assert_checkequal(vectorfind(H, [0 1 2 3], 3), []); // size = 3
81 assert_checkequal(vectorfind(H, [0 1 2], 4), []);   // size = 2
82
83 // Without joker, the matching array is empty 
84 [i,ma] = vectorfind(m, [0 0 1 0], "c");
85 assert_checkequal(ma, []);
86 [i,ma] = vectorfind(m, [0 0 1 0], "c",,"headIJK");
87 assert_checkequal(ma, []);
88
89 // ================
90 // CHECKING RESULTS
91 // ================
92 // ====================
93 // WITH DECIMAL NUMBERS
94 // ====================
95 m = [
96 //1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
97   1  0  0  0  1  0  1  0  1  0  0  1  1  1  1
98   0  0  1  0  0  1  0  1  0  0  0  0  0  0  0
99   0  1  1  1  0  0  1  1  1  0  1  1  0  0  1
100   0  0  1  0  1  0  1  0  1  0  0  0  0  0  1
101   ];
102 assert_checkequal(vectorfind(m, [1 1 1 1 0 0 1 1 1 0 1 1 0 0 1]), []);
103 assert_checkequal(vectorfind(m, [0 1 1 1 0 0 1 1 1 0 1 1 0 0 1]), 3);
104 assert_checkequal(vectorfind(m, [1 0 0 0], "c"), [1 13 14]);
105
106 // With %inf
107 m(2,2) = %inf;
108 assert_checkequal(vectorfind(m, [0 %inf 1 0]), 2);
109
110 // With %nan in the haystack
111 m(2,2) = %nan;
112 assert_checkequal(vectorfind(m, [0 1 1 0], "c"), 8);
113 assert_checkequal(vectorfind(m, [%nan 1]), 6);    // Matches as any other value
114
115 // With short v
116 assert_checkequal(vectorfind(m,[1 0 1],"c"), [25 33 45 57]);
117 assert_checkequal(vectorfind(m,[1 1 0 0],"r"), [11 43]);
118
119 // Option indType
120 assert_checkequal(vectorfind(m, [1 0 0 0], "c"), [1 13 14]);
121 assert_checkequal(vectorfind(m, [1 0 0 0], "c",,"headN"), [1 49 53]);
122 assert_checkequal(vectorfind(m, [1 0 0 0], "c",,"headIJK"), [1 1 ; 1 13 ; 1 14]);
123 assert_checkequal(vectorfind(m, [0 1 1 1 0 0 1 1 1 0 1 1 0 0 1],"r",,"headN"), 3);
124 assert_checkequal(vectorfind(m, [0 1 1 1 0 0 1 1 1 0 1 1 0 0 1],"r",,"headIJK"), [3 1]);
125
126 // With jokers in the needle
127 [ind, ma] = vectorfind(m, [1 -1 -1 0],"c",-1);
128 assert_checkequal(ind, [1 12 13 14]);
129 assert_checkequal(ma, [1 0 0 0; 1 0 1 0; 1 0 0 0; 1 0 0 0]);
130 // With %nan jokers in the needle
131 assert_checkequal(vectorfind(m, [1 %nan %nan 0],"c",%nan), [1 12 13 14]);
132
133 // With %nan in the haystack, ignored by %nan in the needle
134 [ind, ma] = vectorfind(m, [0 %nan 1 0],"c",%nan);
135 assert_checkequal(ind, [2 4 8 11]);
136 assert_checkequal(ma, [0 %nan 1 0; 0 0 1 0; 0 1 1 0; 0 0 1 0]);
137
138 // With %nan jokers in the needle
139 assert_checkequal(vectorfind(m,[1 1 %nan 0],"r",%nan), [7 11 27 43]);
140 assert_checkequal(vectorfind(m,[0 %nan %nan 0 0 1],"r",%nan), [2 39 40]);
141 assert_checkequal(vectorfind(m,[0 %nan 1],"c",%nan), [5 9 13 18 26 29 34 41 58]);
142
143 // Hypermatrix
144 // ===========
145 // Option indType
146     //              dir = "r" = 1
147 assert_checkequal(vectorfind(H, [1 0 0]), [1 10 12]);
148 assert_checkequal(vectorfind(H, [1 0 0], "r",,"headN"), [1 26 32]);
149 res =  [1  1  1  1
150         2  1  2  2
151         2  1  3  2];
152 assert_checkequal(vectorfind(H, [1 0 0], "r",,"headIJK"), res);
153     //              dir = "c" = 2
154 assert_checkequal(vectorfind(H, [0 1], "c"), [3 7 16]);
155 assert_checkequal(vectorfind(H, [0 1], "c",,"headN"), [5 13 31]);
156 res =  [1  3  1  1
157         1  1  3  1
158         1  1  3  2];
159 assert_checkequal(vectorfind(H, [0 1], "c",,"headIJK"), res);
160     //              dir = 3
161 assert_checkequal(vectorfind(H, [0 2 0], 3), [3 7]);
162 assert_checkequal(vectorfind(H, [0 2 0], 3,,"headN"), [3 19]);
163 res =  [1  2  1  1
164         1  1  1  2];
165 assert_checkequal(vectorfind(H, [0 2 0], 3,,"headIJK"), res);
166     //              dir = 4
167 assert_checkequal(vectorfind(H, [0 1], 4), [5 8 11 15]);
168 assert_checkequal(vectorfind(H, [0 1], 4,,"headN"), [5 8 11 15]);
169 res =  [1  3  1  1
170         2  1  2  1
171         1  3  2  1
172         1  2  3  1];
173 assert_checkequal(vectorfind(H, [0 1], 4,,"headIJK"), res);
174
175 // With short v
176 // ------------
177 //  H  =
178 // (:,:,1,1)
179 //    1   0   0
180 //    2   2   1
181 // (:,:,2,1)
182 //    1   2   0
183 //    0   0   2
184 // (:,:,3,1)
185 //    0   0   1
186 //    1   0   2
187 //
188 // (:,:,1,2)
189 //    0   2   1
190 //    0   1   2
191 // (:,:,2,2)
192 //    2   2   1
193 //    1   0   0
194 // (:,:,3,2)
195 //    0   1   2
196 //    1   0   0
197 assert_checkequal(vectorfind(H, [0 1], "r"), [15 20 31]);
198 assert_checkequal(vectorfind(H, [0 1], 1  ), [15 20 31]);
199 res = [1  2  3  1
200        2  1  1  2
201        1  1  3  2];
202 assert_checkequal(vectorfind(H, [0 1], "r",,"headIJK"), res);
203 assert_checkequal(vectorfind(H, 2, "c"), [2 4 9 12 18 21 24 25 27 35]);
204
205 assert_checkequal(vectorfind(H, [0 0], 3), [5 10 28 30]);
206 res = [
207   1  3  1  1
208   2  2  2  1
209   2  2  2  2
210   2  3  2  2];
211 assert_checkequal(vectorfind(H, [0 0], 3,, "headIJK"), res);
212 H2 = matrix(H,1,3,3,4);
213 assert_checkequal(vectorfind(H2, [0 1], 4), [5 8 13 20]);
214 res = [
215   1  2  2  1
216   1  2  3  1
217   1  1  2  2
218   1  2  1  3];
219 assert_checkequal(vectorfind(H2, [0 1], 4,, "headIJK"), res);
220
221 // Additional tests with an hypermatrix haystack
222 // ---------------------------------------------
223 m = matrix(m,4,5,3);
224 m(2,2) = 0;
225 //(:,:,1)
226 //   1   0   0   0   1
227 //   0   0   1   0   0
228 //   0   1   1   1   0
229 //   0   0   1   0   1
230 //(:,:,2)
231 //   0   1   0   1   0
232 //   1   0   1   0   0
233 //   0   1   1   1   0
234 //   0   1   0   1   0
235 //(:,:,3)
236 //   0   1   1   1   1
237 //   0   0   0   0   0
238 //   1   1   0   0   1
239 //   0   0   0   0   1
240 assert_checkequal(vectorfind(m, [1 0 1 1], "c"), [7 9 15]); // linearized columns index
241 assert_checkequal(vectorfind(m, [0 1 0 1 0], "r"), [5 8]);  // linearized rows index
242
243 // Short needle
244 // ------------
245     // default indType = headN
246 assert_checkequal(vectorfind(m, [1 1 0], "c"), 30);
247 assert_checkequal(vectorfind(m, [1 1 1], "r"), [7 27 45 49]);
248 assert_checkequal(vectorfind(m, [1 1], 3), [7 10 11 15 25 27 33]);
249     // indType = headIJK
250 assert_checkequal(vectorfind(m, [1 1 0], "c",,"headIJK"), [2 3 2]);
251 res = [3  2  1
252        3  2  2
253        1  2  3
254        1  3  3];
255 assert_checkequal(vectorfind(m, [1 1 1], "r",,"headIJK"), res);
256 res = [
257   3  2  1
258   2  3  1
259   3  3  1
260   3  4  1
261   1  2  2
262   3  2  2
263   1  4  2];
264 assert_checkequal(vectorfind(m, [1 1], 3,,"headIJK"), res);
265
266 // With jokers in the needle:
267 // -------------------------
268 //  Columns starting and ending with 1:
269 [ind, ma] = vectorfind(m, [1 %nan %nan 1], "c", %nan);
270 assert_checkequal(ind, [5 7 9 15]);
271 assert_checkequal(ma, [1 0 0 1; 1 0 1 1; 1 0 1 1; 1 0 1 1]);
272 //  Rows starting and ending with 1:
273 assert_checkequal(vectorfind(m, [1 %nan %nan %nan 1], "r", %nan), [1 11]);
274 //  Stack starting and ending with 1:
275 [ind, ma] = vectorfind(m, [1 %nan 1], 3, %nan);
276 assert_checkequal(ind, [7 17 20]);
277 assert_checkequal(ma, [1 1 1; 1 0 1; 1 0 1]);
278
279 // With jokers in short needle:
280 // ---------------------------
281 [ind, ma] = vectorfind(m, [1 %nan 1], 2, %nan);
282 assert_checkequal(ind, [10 25 33 45 57]);
283 assert_checkequal(ma, [1 1 1; 1 0 1; 1 0 1; 1 0 1; 1 0 1]);
284 res = [1  2  1
285        3  2  1
286        1  4  1];
287 assert_checkequal(vectorfind(m, [%nan 1 1], 3, %nan, "headIJK"), res);
288
289 // ===================
290 // WITH NUMERIC SPARSE
291 // ===================
292 m = [
293   0  0  1  1  1
294   1  0  0  2  0
295   2  0  2  2  1];
296 m = sparse(m);
297 assert_checkequal(vectorfind(m,[0 0 0],"c"), 2);
298 assert_checkequal(vectorfind(m,[1 0 0 2 0],"r"), 2);
299 // Joker
300 [ind, ma] = vectorfind(m,[1 %nan 2],"c", %nan);
301 assert_checkequal(ind, [3 4]);
302 assert_checkequal(ma, sparse([1 0 2 ; 1 2 2]));
303 // Short needle
304 assert_checkequal(vectorfind(m,[0 0],"r"), [1 5]);
305 // Short needle with joker
306 [ind, ma] = vectorfind(m,[0 %nan 2],"r", %nan);
307 assert_checkequal(ind, [5 6]);
308 assert_checkequal(ma, sparse([0 0 2 ; 0 2 2]));
309
310
311 // ==========
312 // WITH TEXTS
313 // ==========
314 m  = [
315 // 1    2    3    4    5    6    7    8    9   10   11   12
316   "U"  "C"  "G"  "A"  "A"  "A"  "U"  "U"  "A"  "G"  "A"  "G"
317   "A"  "A"  "A"  "A"  "C"  "C"  "U"  "U"  "C"  "G"  "G"  "G"
318   "A"  "G"  "A"  "C"  "G"  "C"  "C"  "C"  "G"  "C"  "A"  "G"
319   "C"  "U"  "G"  "G"  "G"  "A"  "A"  "G"  "C"  "C"  "C"  "C"
320   "C"  "G"  "G"  "A"  "A"  "G"  "U"  "C"  "A"  "U"  "G"  "C"
321   ];
322 // U  C  G  A  A  A  U  U  A  G  A  G
323 // A  A  A  A  C  C  U  U  C  G  G  G
324 // A  G  A  C  G  C  C  C  G  C  A  G
325 // C  U  G  G  G  A  A  G  C  C  C  C
326 // C  G  G  A  A  G  U  C  A  U  G  C
327 assert_checkequal(vectorfind(m, ["A" "C" "C" "A" "G"], "c"), 6);
328 assert_checkequal(vectorfind(m, ["C" "U" "G" "G" "G" "A" "A" "G" "C" "C" "C" "C"],"r"), 4);
329
330 // Short needle
331 assert_checkequal(vectorfind(m, ["A" "C" "G"], "c"), [17 21 41 53]);
332 assert_checkequal(vectorfind(m, ["A" "C" "G"], "r"), 13);
333 // With joker
334 [ind, ma] = vectorfind(m, ["A" "" "" "" "A"], "c", "");
335 assert_checkequal(ind, [4 5 9]);
336 assert_checkequal(ma, ["A" "A" "C" "G" "A"; "A" "C" "G" "G" "A"; "A" "C" "G" "C" "A"] );
337 // With joker in short needle
338 [ind, ma] = vectorfind(m, ["A" "" "U" "" "G"], "r", "");
339 assert_checkequal(ind, 26);
340 assert_checkequal(ma, ["A" "U" "U" "A" "G"]);
341
342 // Text hypermat:
343 // -------------
344 m = matrix(m,3,5,4);
345 // m  =
346 //(:,:,1)
347 //!U  C  A  G  A  !
348 //!A  C  G  G  G  !
349 //!A  C  U  A  G  !
350 //(:,:,2)
351 //!A  G  C  A  C  !
352 //!A  A  G  A  A  !
353 //!C  A  G  C  G  !
354 //(:,:,3)
355 //!U  A  U  C  G  !
356 //!U  U  C  A  C  !
357 //!C  U  G  C  A  !
358 //(:,:,4)
359 //!G  C  G  G  G  !
360 //!G  U  A  G  C  !
361 //!C  A  C  G  C  !
362 assert_checkequal(vectorfind(m, ["A" "A" "C"], "c"), [6 9]);
363 assert_checkequal(vectorfind(m, ["" "G" "G"], "c", ""), [5 8 19]);
364 // Joker
365 [ind, ma] = vectorfind(m, ["" "G" "G"], "c", "","headN");
366 assert_checkequal(ind, [13 22 55]);
367 assert_checkequal(ma, ["A" "G" "G"; "C" "G" "G"; "G" "G" "G"]);
368 res = [
369   1  2  1
370   1  5  4];
371 assert_checkequal(vectorfind(m, ["" "C" "C"], "c", "", "headIJK"), res);
372 // Short needle
373 res = [
374   1  2  1
375   2  2  1
376   2  5  4];
377 assert_checkequal(vectorfind(m, ["C" "C"], "c",,"headIJK"), res);
378 // Short needle with joker
379 res = [
380   1  3  1
381   2  2  2];
382 assert_checkequal(vectorfind(m, ["A" "" "A"],"r","","headIJK"), res);
383
384 // =============
385 // WITH BOOLEANS
386 // =============
387 m = asciimat(m(:,:,1:3))<70;
388 // m  =
389 // (:,:,1)
390 //  F T T F T
391 //  T T F F F
392 //  T T F T F
393 // (:,:,2)
394 //  T F T T T
395 //  T T F T T
396 //  T T F T F
397 // (:,:,3)
398 //  F T F T F
399 //  F F T T T
400 //  T F F T T
401 assert_checkequal(vectorfind(m, [%T %T %T],"c"), [2 6 9 14]);
402 // short needle
403 assert_checkequal(vectorfind(m, [%T %T %T],"r"), [22 38]);
404 res = [
405   1  3  2
406   2  3  3];
407 assert_checkequal(vectorfind(m, [%T %T %T],"r",,"headIJK"), res);
408 // Joker: Note that v and joker are numerical
409 [ind, ma] = vectorfind(m, [0 2 1],"c",2);
410 assert_checkequal(ind, [1 4 7 11 15]);
411 assert_checkequal(ma, [0 1 1; 0 0 1; 0 1 1; 0 0 1; 0 1 1]==1);
412 // Short needle with joker
413 res = [
414   1  1  2
415   2  2  2
416   3  1  3];
417 assert_checkequal(vectorfind(m, [1 0 2 1],"r",2, "headIJK"), res);