* Bug #12059 fixed - Index returned by gsort of sparse were wrong.
[scilab.git] / scilab / modules / elementary_functions / macros / %sp_gsort.sci
index 9b96fcc..208f20c 100644 (file)
@@ -8,55 +8,74 @@
 // are also available at    \r
 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt\r
 \r
-function A = %sp_gsort(A, optsort, directionsort)\r
+function [A, k] = %sp_gsort(A, optsort, directionsort)\r
     rhs = argn(2);\r
+    lhs = argn(1);\r
+    // arguments by default in gsort\r
     select rhs\r
     case 1\r
         optsort = 'g';\r
         directionsort = 'd';\r
     case 2\r
+        // optsort can be: 'r', 'c', 'g', 'lr', 'lc'\r
+        pos_opts = find(optsort == ['r', 'c', 'g', 'lr', 'lc']);\r
+        if pos_opts == [] then\r
+            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
+        end\r
         directionsort = 'd';\r
+    else\r
+        // optsort can be: 'r', 'c', 'g', 'lr', 'lc'\r
+        pos_opts = find(optsort == ['r', 'c', 'g', 'lr', 'lc']);\r
+        // directionsort can be: 'd' or 'i'\r
+        pos_direction = find(directionsort == ['d', 'i']);\r
+        if pos_opts == [] then\r
+            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
+        end\r
+        if pos_direction == [] then\r
+            error(msprintf(_("%s: Wrong value for input argument #%d: ''%s'' or ''%s'' expected.\n"), "gsort", 3, "d", "i"));\r
+        end\r
     end\r
 \r
     [ij, v, mn] = spget(A);\r
-\r
     if mn(1) <> 1 & mn(2) <> 1 then\r
-        error(999,msprintf(_("%s: Wrong size for input argument #%d: sparse vectors expected.\n"),'gsort',1));\r
+        error(999,msprintf(_("%s: Wrong size for input argument #%d: sparse vectors expected.\n"), 'gsort', 1));\r
     end\r
 \r
-    if (strcmp(optsort, 'c')) == 0 | v == [] then\r
-        A = A;\r
-    else\r
-        if mn(2) == 1 then\r
-            dif = mn(1) - length(v);\r
-            v = gsort(v, optsort, directionsort);\r
-            \r
-            last = find(v<0);\r
-            first = find(v>0);\r
-            \r
-            if last == [] & first <> [] then\r
-                if strcmp(directionsort, 'i')== 0 then\r
-                    ij(:,1) = first(:) + dif;\r
+    if mn(1) == 1 then\r
+        // if A is a row vector and optsort = 'r', the result is the \r
+        // first input argument\r
+        if strcmp(optsort, 'r') == 0 |strcmp(optsort, 'lr') == 0 | v == [] then\r
+            A = A;\r
+            if lhs == 2 then\r
+                if strcmp(optsort, 'lr') == 0 | ij == [] then\r
+                    k = 1;\r
                 else\r
-                    ij(:,1) = first(:);\r
-                end\r
-            elseif first == [] & last <> [] then\r
-                ij(:,1) = last(:) + dif;\r
-            else\r
-                if strcmp(directionsort, 'i')== 0 then\r
-                    ij(:,1) = [last(:); first(:) + dif];\r
-                else\r
-                    ij(:,1) = [first(:); last(:) + dif];\r
+                    k = ij(:,1);\r
+                    k = k';\r
                 end\r
             end\r
-            \r
-        elseif mn(1) == 1 then\r
+        else\r
             dif = mn(2) - length(v);\r
-            v = gsort(v, optsort, directionsort);\r
-            \r
-            last = find(v<0);\r
-            first = find(v>0);\r
-            \r
+            if lhs == 1 then\r
+                v = gsort(v', optsort, directionsort);\r
+            else\r
+                [v, k] = gsort(v', optsort, directionsort);\r
+                k=ij(k,2)';\r
+            end\r
+\r
+            //Obtain the indices corresponding to positive values of v\r
+            // and negative value of v\r
+            // If A is complex, the elements are sorted by magnitude\r
+            if isreal(A) then\r
+                last = find(v<0);\r
+                first = find(v>0);\r
+            else\r
+                s = abs(v);\r
+                last = find(s<0);\r
+                first = find(s>0);\r
+            end\r
+\r
+            // Sort the indices\r
             if last == [] & first <> [] then\r
                 if strcmp(directionsort, 'i')== 0 then\r
                     ij(:,2) = first(:) + dif;\r
@@ -64,7 +83,11 @@ function A = %sp_gsort(A, optsort, directionsort)
                     ij(:,2) = first(:);\r
                 end\r
             elseif first == [] & last <> [] then\r
-                ij(:,1) = last(:) + dif;\r
+                if strcmp(directionsort, 'i')== 0 then\r
+                    ij(:,1) = last(:);\r
+                else\r
+                    ij(:,1) = last(:) + dif;\r
+                end\r
             else\r
                 if strcmp(directionsort, 'i')== 0 then\r
                     ij(:,2) = [last(:); first(:) + dif];\r
@@ -72,12 +95,75 @@ function A = %sp_gsort(A, optsort, directionsort)
                     ij(:,2) = [first(:); last(:) + dif];\r
                 end\r
             end\r
-            \r
+            A = sparse(ij,v,mn);\r
         end\r
-        A = sparse(ij, v, mn)\r
     end\r
 \r
-endfunction\r
+    if mn(2) == 1 then\r
+        // if A is a column vector and optsort = 'c', the result is the \r
+        // first input argument\r
+        if strcmp(optsort, 'c') == 0 | strcmp(optsort, 'lc') == 0 | v == [] then\r
+            A = A;\r
+            if lhs == 2 then\r
+                if strcmp(optsort, 'lc') == 0 | ij == [] then\r
+                    k = 1;\r
+                else\r
+                    k = ij(:,2);\r
+                    k = k;\r
+                end\r
+            end\r
+        else\r
+\r
+            dif = mn(1) - length(v);\r
+            if lhs == 1 then\r
+                v = gsort(v, optsort, directionsort);\r
+            else\r
+                [v, k] = gsort(v, optsort, directionsort);\r
+                k=ij(k,1);\r
+            end\r
 \r
+            //Obtain the indices corresponding to positive values of v\r
+            // and negative value of v\r
+            // If A is complex, the elements are sorted by magnitude\r
+            if isreal(A) then\r
+                last = find(v<0);\r
+                first = find(v>0);\r
+            else\r
+                s = abs(v);\r
+                last = find(s<0);\r
+                first = find(s>0);\r
+            end\r
 \r
-\r\r
+            // sort the indices in terms of directionsort = 'i' or 'd'\r
+            // if directionsort='i' and v>0, the elements are sorted in the \r
+            // increasing order, ie [0,..,v] and, conversely, in the decreasing\r
+            // order the elements are sorted : [v,..,0]\r
+            // if v<0, the elements are sorted in the increasing order, \r
+            // ie [v,..,0] and, conversely, in the decreasing order the \r
+            // elements are sorted : [0,..,v]\r
+            // And else, if v contains positive and neqative values, the \r
+            // elements are sorted in the increasing order,ie [v_neg,0,v_pos],\r
+            // and conversely for the decreasing order.\r
+            if last == [] & first <> [] then\r
+                if strcmp(directionsort, 'i') == 0 then\r
+                    ij(:,1) = first(:) + dif;\r
+                else\r
+                    ij(:,1) = first(:);\r
+                end\r
+            elseif first == [] & last <> [] then\r
+                if strcmp(directionsort, 'i') == 0 then\r
+                    ij(:,1) = last(:);\r
+                else\r
+                    ij(:,1) = last(:) + dif;\r
+                end\r
+            else\r
+                if strcmp(directionsort, 'i') == 0 then\r
+                    ij(:,1) = [last(:); first(:) + dif];\r
+                else\r
+                    ij(:,1) = [first(:); last(:) + dif];\r
+                end\r
+            end\r
+            A = sparse(ij, v, mn);\r
+        end\r
+    end\r
+endfunction\r