* Bug #12059 fixed - Index returned by gsort of sparse were wrong.
[scilab.git] / scilab / modules / elementary_functions / macros / %sp_gsort.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab\r
2 // Copyright (C) DIGITEO - 2009 - Allan CORNET\r
3 // Copyrifht (C) 2012 - Scilab Enterprises - Adeline CARNIS\r
4 // \r
5 // This file must be used under the terms of the CeCILL.\r
6 // This source file is licensed as described in the file COPYING, which\r
7 // you should have received as part of this distribution.  The terms\r
8 // are also available at    \r
9 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt\r
10 \r
11 function [A, k] = %sp_gsort(A, optsort, directionsort)\r
12     rhs = argn(2);\r
13     lhs = argn(1);\r
14     // arguments by default in gsort\r
15     select rhs\r
16     case 1\r
17         optsort = 'g';\r
18         directionsort = 'd';\r
19     case 2\r
20         // optsort can be: 'r', 'c', 'g', 'lr', 'lc'\r
21         pos_opts = find(optsort == ['r', 'c', 'g', 'lr', 'lc']);\r
22         if pos_opts == [] then\r
23             error(msprintf(_("%s: Wrong value for input argument #%d: ''%s'', ''%s'', ''%s'', ''%s'' or ''%s'' expected.\n"), "gsort", 2, "r", "c", "g", "lr", "lc"));\r
24         end\r
25         directionsort = 'd';\r
26     else\r
27         // optsort can be: 'r', 'c', 'g', 'lr', 'lc'\r
28         pos_opts = find(optsort == ['r', 'c', 'g', 'lr', 'lc']);\r
29         // directionsort can be: 'd' or 'i'\r
30         pos_direction = find(directionsort == ['d', 'i']);\r
31         if pos_opts == [] then\r
32             error(msprintf(_("%s: Wrong value for input argument #%d: ''%s'', ''%s'', ''%s'', ''%s'' or ''%s'' expected.\n"), "gsort", 2, "r", "c", "g", "lr", "lc"));\r
33         end\r
34         if pos_direction == [] then\r
35             error(msprintf(_("%s: Wrong value for input argument #%d: ''%s'' or ''%s'' expected.\n"), "gsort", 3, "d", "i"));\r
36         end\r
37     end\r
38 \r
39     [ij, v, mn] = spget(A);\r
40     if mn(1) <> 1 & mn(2) <> 1 then\r
41         error(999,msprintf(_("%s: Wrong size for input argument #%d: sparse vectors expected.\n"), 'gsort', 1));\r
42     end\r
43 \r
44     if mn(1) == 1 then\r
45         // if A is a row vector and optsort = 'r', the result is the \r
46         // first input argument\r
47         if strcmp(optsort, 'r') == 0 |strcmp(optsort, 'lr') == 0 | v == [] then\r
48             A = A;\r
49             if lhs == 2 then\r
50                 if strcmp(optsort, 'lr') == 0 | ij == [] then\r
51                     k = 1;\r
52                 else\r
53                     k = ij(:,1);\r
54                     k = k';\r
55                 end\r
56             end\r
57         else\r
58             dif = mn(2) - length(v);\r
59             if lhs == 1 then\r
60                 v = gsort(v', optsort, directionsort);\r
61             else\r
62                 [v, k] = gsort(v', optsort, directionsort);\r
63                 k=ij(k,2)';\r
64             end\r
65 \r
66             //Obtain the indices corresponding to positive values of v\r
67             // and negative value of v\r
68             // If A is complex, the elements are sorted by magnitude\r
69             if isreal(A) then\r
70                 last = find(v<0);\r
71                 first = find(v>0);\r
72             else\r
73                 s = abs(v);\r
74                 last = find(s<0);\r
75                 first = find(s>0);\r
76             end\r
77 \r
78             // Sort the indices\r
79             if last == [] & first <> [] then\r
80                 if strcmp(directionsort, 'i')== 0 then\r
81                     ij(:,2) = first(:) + dif;\r
82                 else\r
83                     ij(:,2) = first(:);\r
84                 end\r
85             elseif first == [] & last <> [] then\r
86                 if strcmp(directionsort, 'i')== 0 then\r
87                     ij(:,1) = last(:);\r
88                 else\r
89                     ij(:,1) = last(:) + dif;\r
90                 end\r
91             else\r
92                 if strcmp(directionsort, 'i')== 0 then\r
93                     ij(:,2) = [last(:); first(:) + dif];\r
94                 else\r
95                     ij(:,2) = [first(:); last(:) + dif];\r
96                 end\r
97             end\r
98             A = sparse(ij,v,mn);\r
99         end\r
100     end\r
101 \r
102     if mn(2) == 1 then\r
103         // if A is a column vector and optsort = 'c', the result is the \r
104         // first input argument\r
105         if strcmp(optsort, 'c') == 0 | strcmp(optsort, 'lc') == 0 | v == [] then\r
106             A = A;\r
107             if lhs == 2 then\r
108                 if strcmp(optsort, 'lc') == 0 | ij == [] then\r
109                     k = 1;\r
110                 else\r
111                     k = ij(:,2);\r
112                     k = k;\r
113                 end\r
114             end\r
115         else\r
116 \r
117             dif = mn(1) - length(v);\r
118             if lhs == 1 then\r
119                 v = gsort(v, optsort, directionsort);\r
120             else\r
121                 [v, k] = gsort(v, optsort, directionsort);\r
122                 k=ij(k,1);\r
123             end\r
124 \r
125             //Obtain the indices corresponding to positive values of v\r
126             // and negative value of v\r
127             // If A is complex, the elements are sorted by magnitude\r
128             if isreal(A) then\r
129                 last = find(v<0);\r
130                 first = find(v>0);\r
131             else\r
132                 s = abs(v);\r
133                 last = find(s<0);\r
134                 first = find(s>0);\r
135             end\r
136 \r
137             // sort the indices in terms of directionsort = 'i' or 'd'\r
138             // if directionsort='i' and v>0, the elements are sorted in the \r
139             // increasing order, ie [0,..,v] and, conversely, in the decreasing\r
140             // order the elements are sorted : [v,..,0]\r
141             // if v<0, the elements are sorted in the increasing order, \r
142             // ie [v,..,0] and, conversely, in the decreasing order the \r
143             // elements are sorted : [0,..,v]\r
144             // And else, if v contains positive and neqative values, the \r
145             // elements are sorted in the increasing order,ie [v_neg,0,v_pos],\r
146             // and conversely for the decreasing order.\r
147             if last == [] & first <> [] then\r
148                 if strcmp(directionsort, 'i') == 0 then\r
149                     ij(:,1) = first(:) + dif;\r
150                 else\r
151                     ij(:,1) = first(:);\r
152                 end\r
153             elseif first == [] & last <> [] then\r
154                 if strcmp(directionsort, 'i') == 0 then\r
155                     ij(:,1) = last(:);\r
156                 else\r
157                     ij(:,1) = last(:) + dif;\r
158                 end\r
159             else\r
160                 if strcmp(directionsort, 'i') == 0 then\r
161                     ij(:,1) = [last(:); first(:) + dif];\r
162                 else\r
163                     ij(:,1) = [first(:); last(:) + dif];\r
164                 end\r
165             end\r
166             A = sparse(ij, v, mn);\r
167         end\r
168     end\r
169 endfunction\r