a5f5591087ec2e7e8d60f027ff4e985d06ff430f
[scilab.git] / scilab / modules / elementary_functions / tests / unit_tests / gsort_multilevel_complex.tst
1 // ===================================================================
2 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 // Copyright (C) ????-2008 - INRIA
4 // Copyright (C) ????-2008 - ENPC
5 // Copyright (C) 2008 - DIGITEO - Allan CORNET
6 // Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
7 // Copyright (C) 2018-2020 - Samuel GOUGEON
8 //
9 //  This file is distributed under the same license as the Scilab package.
10 // ===================================================================
11
12 // <-- CLI SHELL MODE -->
13 // <-- NO CHECK REF -->
14
15 //================================ sparse complex ====================
16 //  Tests in gsort_sparse.tst
17 //
18 //================================ complex matrix ====================
19 /*
20 i = %i;
21 c  = [
22 i         -1. - i    -i         -i       
23 1. - i    -1.         1.         1. + i  
24 -1. + i     1.         0.         0.      
25 i         -1. + i     1.         1. - i  
26 0.         1. - i     1. + i     0.      
27 1.        -1. - i    -1.        -1. + i  
28 i         -1. + i    -1. + i    -i       
29 1. - i    -1.         1.         1. + i  
30 -1. + i    -i         -1.        -i       
31 ];
32 */
33
34 x = [3  1  5 ; 2 9 8];
35 y = [2  4  1 ; 4 1 3];
36 c = x + y * %i;
37
38 ref_ind = [  4.    5.    3.  ;    6.    2.    1.  ];
39 ref_values = [ 9 +   %i, 5 +   %i,  1 + 4*%i
40 8 + 3*%i, 2 + 4*%i,  3 + 2*%i ];
41 [v,ind] = gsort(c);
42 assert_checkequal(ref_ind, ind);
43 assert_checkequal(ref_values, v);
44
45 [v1,ind1] = gsort(abs(c));
46 [v2,ind2] = gsort(c);
47 assert_checkequal(ind1, ind2);
48
49 A = [18 21 10 7 5];
50 B = [1  3  22 8 4];
51 y = complex(A,B);
52 [a,b] = gsort(y);
53 assert_checkequal(b, [3 2 1 4 5]);
54 assert_checkequal(y(b), a);
55
56 refMsg = msprintf(_("%s: Argument #%d: Must be in the set {%s}.\n"), "gsort", 2, "''g'',''r'',''c'',''lc'',''lr''");
57 assert_checkerror("[a,b] = %s_gsort(y,''l'')", refMsg);
58
59 ierr = execstr("[a,b] = %s_gsort(y,''g'');","errcatch");
60 assert_checkequal(ierr, 0);
61
62 ierr = execstr("[a,b] = %s_gsort(y,''r'');","errcatch");
63 assert_checkequal(ierr, 0);
64
65 ierr = execstr("[a,b] = %s_gsort(y,''c'');","errcatch");
66 assert_checkequal(ierr, 0);
67
68 ierr = execstr("[a,b] = %s_gsort(y,''lc'');","errcatch");
69 assert_checkequal(ierr, 0);
70
71 ierr = execstr("[a,b] = %s_gsort(y,''lr'');","errcatch");
72 assert_checkequal(ierr, 0);
73
74 // -------------------------------------------------------------------
75 // Error messages
76 // -------------------------------------------------------------------
77 msg = msprintf(_("%s: Argument #%d: Must be in the set {%s}.\n"), "gsort", 2, "''g'',''r'',''c'',''lc'',''lr''");
78 assert_checkerror("%s_gsort(%i,''q'')", msg);
79 msg = msprintf(_("%s: Argument #%d: Text(s) expected.\n"), "gsort", 3);
80 assert_checkerror("%s_gsort(%i,''g'',1)", msg);
81
82 msg = msprintf(_("%s: Argument #%d: Must be in the set {%s}.\n"), "gsort", 3, "''i'',''d''");
83 assert_checkerror("%s_gsort(%i,''g'',''a'')", msg);
84 msg = "gsort: Argument #4: List expected.";
85 assert_checkerror("%s_gsort(%i,''g'',''i'', 1)", msg);
86 msg = "gsort: Arguments #3 and #4: Same numbers of elements expected.";
87 assert_checkerror("%s_gsort(%i,''g'',''i'', list())", msg);
88 assert_checkerror("%s_gsort(%i,''g'',''i'', list(real, imag))", msg);
89 msg = "gsort: Arguments #3 and #4: Same numbers of elements expected.";
90 assert_checkerror("%s_gsort(%i,''g'',''i'', list())", msg);
91 msg = "gsort: Argument #4: List of functions identifiers expected.";
92 assert_checkerror("%s_gsort(%i,''g'',''i'', list(1))", msg);
93
94 // ===================================================================
95 //              Other tests with DENSE matrices of COMPLEX numbers
96 // ===================================================================
97 function r = getBuiltinName(b)
98     select b
99     case real
100         r = "real"
101     case imag
102         r = "imag"
103     case abs
104         r = "abs"
105     case atan
106         r = "atan"
107     else
108         r = "unknown"
109     end
110 endfunction
111
112 function r = getDecimalData(C, crit)
113     if crit==atan
114         r = atan(imag(C), real(C))
115     else
116         r = crit(C)
117     end
118 endfunction
119 function checkComplexOrderVec(Vs1, Vs2, Vks, ord2)
120     for j = 2:length(Vs1)
121         mprintf("%d ",j);
122         if Vs1(j)==Vs1(j-1)
123             if ord2=="i"
124                 assert_checktrue(Vs2(j)>=Vs2(j-1));
125             else
126                 assert_checktrue(Vs2(j)<=Vs2(j-1));
127             end
128             if Vs2(j)==Vs2(j-1) // => check initial order preserved
129                 assert_checktrue(Vks(j)>Vks(j-1));
130             end
131         end
132     end
133 endfunction
134 // -------------------------------------------------------------------
135 function checkComplexOrder(C, Cs, ks, method, order, crits)
136     ord1 = order(1);
137     Cs1 = getDecimalData(Cs, crits(1));
138     // Checking the order according to the first criteria:
139     //   If the Cs order is correct, its first criteria part should have the
140     //   same order than the sorted C (necessary but not sufficient condition).
141     //   This should be true for all methods, but only for values: Indices of
142     //   equal first part values can be changed by the second criteria
143     // FIRST CRITERION
144     // ---------------
145     C1 = getDecimalData(C, crits(1));
146     [C1ref, k1] = gsort(C1, method, ord1);
147     if and(method~=["lr" "lc"]) | (size(order,"*")==1 | size(crits)<2) then
148         assert_checkalmostequal(Cs1, C1ref);
149     end
150     // SINGLE CRITERIA
151     // ---------------
152     if size(order,"*")==1 | size(crits)<2
153         // then we can compare directly k1 and ks: they must be equal
154         assert_checkequal(ks, k1);
155         // We assume that gsort() works correctly with reals.
156         // So we do not check here the actual order of Cs1 values and the
157         // correctness of ks indices.
158         // These checking should be done by tests with reals.
159         mprintf("\n");
160         return
161     end
162     // SECOND CRITERIA
163     // ---------------
164     ord2 = order(2);
165     if or(method==["g" "r" "c"]) then
166         Cs2 = getDecimalData(Cs, crits(2));
167         if method=="g"
168             checkComplexOrderVec(Cs1, Cs2, ks, ord2);
169         elseif method=="r"
170             for col = 1:size(C,2)
171                 checkComplexOrderVec(Cs1(:,col), Cs2(:,col), ks(:,col), ord2);
172             end
173         elseif method=="c"
174             for row = 1:size(C,1)
175                 checkComplexOrderVec(Cs1(row,:), Cs2(row,:), ks(row,:), ord2);
176             end
177         end
178         mprintf("\n");
179     else // lr, lc
180         mprintf("  %s: values unchecked\n", method);
181     end
182 endfunction
183
184 clc
185 [nr, nc] = (6,6);
186 r = grand(nr, nc, "uin", -1, 1);
187 i = grand(nr, nc, "uin", -1, 1);
188 C = r + i*%i;
189 sizeC = size(C);
190 colNan = ones(C(:,1))*%nan;
191 crits = list(real, imag, abs, atan);
192
193 // ================
194 // SINGLE CRITERION
195 // ================
196 methods = ["g" "r" "c" "lr" "lc"];
197 for m = methods
198     for  sdir = ["i" "d"]
199         for c = crits
200             mprintf("%s  %s  %s", m, sdir, getBuiltinName(c));
201             [sC, k]  = %s_gsort(C, m, sdir, list(c));
202             checkComplexOrder(C, sC, k, m, sdir, list(c));
203         end
204     end
205 end
206 // -------------------------------------------------------------------
207 // ============
208 // TWO CRITERIA
209 // ============
210 [nr, nc] = (10,3);
211 r = grand(nr, nc, "uin",-1,1);
212 i = grand(nr, nc, "uin",-1,1);
213 C = r+i*%i;
214 sizeC = size(C);
215 colNan = ones(C(:,1))*%nan;
216
217 methods = ["g" "c" "r" "lr" "lc"];
218 crits = list(real, imag, abs, atan);
219 for m = methods
220     for sdir = ["i" "i" ; "i" "d" ; "d" "i" ; "d" "d"]'
221         for c1 = crits
222             for c2 = crits
223                 if c1 == c2
224                     continue
225                 end
226                 crit = list(c1, c2);
227                 mprintf("%s  %s  %s  %s : ", m, strcat(sdir), ..
228                 getBuiltinName(c1), getBuiltinName(c2));
229                 [sC, k]  = %s_gsort(C, m, sdir, crit);
230                 // Check values
231                 checkComplexOrder(C, sC, k, m, sdir, crit);
232                 // Check indices:
233                 if m=="g"
234                     assert_checkequal(sC, matrix(C(k),sizeC));
235                 elseif m=="c"
236                     // get linearized indices:
237                     ak = (1:nr)'*ones(1,nc)+(k-1)*nr;
238                     assert_checkequal(sC, matrix(C(ak),sizeC));
239                 elseif m=="r"
240                     // get linearized indices:
241                     ak = ones(nr,1)*(0:nc-1)*10 + k;
242                     assert_checkequal(sC, matrix(C(ak),sizeC));
243                 elseif m=="lc"
244                     assert_checktrue(isrow(k));
245                     assert_checkequal(sC, C(:,k));
246                 else // m=="lr"
247                     assert_checktrue(iscolumn(k));
248                     assert_checkequal(sC, C(k,:));
249                 end
250             end
251         end
252     end
253 end
254
255 // -------------------------------------------------------------------
256 // Incomplete sorting
257 // -------------------------------------------------------------------
258 m = complex([7  6  9  2  8  1  0  4  3  2], 0);
259 assert_checkequal(%s_gsort(m, "g", "i", list(atan)), m);
260 assert_checkequal(%s_gsort(m, "g", "i", list(imag)), m);
261 assert_checkequal(%s_gsort(m, "g", ["i" "i"], list(imag, atan)), m);
262 assert_checkequal(%s_gsort(m+%i, "g", "d", list(imag)), m+%i);
263
264 // -------------------------------------------------------------------
265 // Double sorting criteria with Nan values in the secondary criterion
266 // -------------------------------------------------------------------
267 c = [-1 1 ; -1 0; 0 2; 0 %nan; 0 -1; 0 %inf ; 0 1; 1 %nan ; 1 1; 1 -1];
268 c = complex(c(:,1), c(:,2))
269 // 1   -1. +    i
270 // 2   -1.
271 // 3          2.i
272 // 4         Nani
273 // 5           -i
274 // 6         Infi
275 // 7            i
276 // 8    1. + Nani
277 // 9    1. +    i
278 // 10   1. -    i
279 [v, k] = %s_gsort(c, "g", "i");
280 assert_checkequal(k, [2  5  7  1  9  10  3  6  4  8]');
281 [v, k] = %s_gsort(c, "g", ["i" "i"], list(real, imag));
282 assert_checkequal(k, [2  1  5  7  3  6  4  10  9  8]');
283 [v, k] = %s_gsort(c,"g", ["i" "d"], list(real, imag));
284 assert_checkequal(k, [1  2  4  6  3  7  5  8  9  10]');
285 [v, k] = %s_gsort(c,"g", ["d" "i"], list(real, imag));
286 assert_checkequal(k, [10  9  8  5  7  3  6  4  2  1]');