* Bug 16245 fixed: gsort() did not sort booleans 25/21125/4
Samuel GOUGEON [Sun, 10 Nov 2019 19:43:23 +0000 (20:43 +0100)]
  http://bugzilla.scilab.org/16245

Change-Id: I77ac8a9f376181e08b5f78c6ed0f61d5bec273ce

scilab/CHANGES.md
scilab/modules/elementary_functions/help/en_US/searchandsort/gsort.xml
scilab/modules/elementary_functions/help/ru_RU/searchandsort/gsort.xml
scilab/modules/elementary_functions/macros/%b_gsort.sci [new file with mode: 0644]
scilab/modules/elementary_functions/macros/%hm_gsort.sci
scilab/modules/elementary_functions/tests/unit_tests/gsort_boolean.tst [new file with mode: 0644]

index 8b81d44..f219f04 100644 (file)
@@ -262,6 +262,7 @@ Bug Fixes
 * [#16210](http://bugzilla.scilab.org/show_bug.cgi?id=16210): The uicontrol.units = "normalized" property was not described.
 * [#16227](http://bugzilla.scilab.org/show_bug.cgi?id=16227): `WSCI` was not defined as environment variable and could not be used as `%WSCI%` in commands sent with `host()` or `unix_*()`.
 * [#16242](http://bugzilla.scilab.org/show_bug.cgi?id=16242): `loadmatfile()` could not read Octave native text data files.
+* [#16245](http://bugzilla.scilab.org/show_bug.cgi?id=16245): `gsort` could not sort booleans.
 * [#16257](http://bugzilla.scilab.org/show_bug.cgi?id=16257): `blockdiag()` implemented to replace `sysdiag()`, improved and extended to strings.
 * [#16260](http://bugzilla.scilab.org/show_bug.cgi?id=16260): overloading `nnz` was not possible (regression).
 * [#16263](http://bugzilla.scilab.org/show_bug.cgi?id=16263): Polynomial insertion was broken for complex case.
index 35a759c..622064b 100644 (file)
@@ -31,8 +31,9 @@
             <varlistentry>
                 <term>A</term>
                 <listitem>
-                    <para>a real,an integer or a character string vector/matrix or a
-                        sparse vector.
+                    <para>
+                        scalar, vector, matrix or hypermatrix of booleans, integers, real numbers,
+                        or text, or a sparse vector of reals.
                     </para>
                 </listitem>
             </varlistentry>
                 <revnumber>5.4.0</revnumber>
                 <revremark>This function allows overloading for unmanaged type (others than a real, an integer or a character string vector/matrix or a sparse vector).</revremark>
             </revision>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revremark>
+                    Booleans can now be sorted.
+                </revremark>
+            </revision>
         </revhistory>
     </refsection>
 </refentry>
index ef70743..ab3bc36 100644 (file)
@@ -31,7 +31,9 @@
             <varlistentry>
                 <term>A</term>
                 <listitem>
-                    <para>вещественный, целочисленный или строковый вектор/матрица, либо разрежённый вектор.
+                    <para>
+                        scalar, vector, matrix or hypermatrix of booleans, integers, real numbers,
+                        or text, or a sparse vector of reals.
                     </para>
                 </listitem>
             </varlistentry>
                     Эта функция позволяет делать перегрузку для типов, которые не управляются (отличные от матриц/векторов вещественных, целочисленных или символьных значений, либо разрежённого вектора).
                 </revremark>
             </revision>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revremark>
+                    Booleans can now be sorted.
+                </revremark>
+            </revision>
         </revhistory>
     </refsection>
 </refentry>
diff --git a/scilab/modules/elementary_functions/macros/%b_gsort.sci b/scilab/modules/elementary_functions/macros/%b_gsort.sci
new file mode 100644 (file)
index 0000000..30418fc
--- /dev/null
@@ -0,0 +1,24 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+//
+// Copyright (C) 2019 - Samuel GOUGEON
+//
+// This file is hereby licensed under the terms of the GNU GPL v2.0,
+// pursuant to article 5.3.4 of the CeCILL v.2.1.
+// This file was originally licensed under the terms of the CeCILL v2.1,
+// and continues to be available under such terms.
+// For more information, see the COPYING file which you should have received
+// along with this program.
+
+function varargout = %b_gsort(varargin)
+    // Boolean hypermatrices are completely processed in %hm_gsort
+
+    b = iconvert(varargin(1), 1);
+    if argn(1)==1 then
+        b = gsort(b, varargin(2:$))==int8(1);
+        varargout = list(b);
+    else
+        [b, k] = gsort(b, varargin(2:$));
+        b = (b == int8(1));
+        varargout = list(b, k);
+    end
+endfunction
index ee72bc0..8b24fc2 100644 (file)
 function [S, k] = %hm_gsort(A, optsort, directionsort)
     rhs = argn(2);
     lhs = argn(1);
+    AisBool = typeof(A)=="boolean"
+    if AisBool
+        A = iconvert(A,1) // int8
+    end
+
     // arguments by default in gsort
     select rhs
     case 1
@@ -92,4 +97,7 @@ function [S, k] = %hm_gsort(A, optsort, directionsort)
             k = matrix(k, sizesInd);
         end
     end
+    if AisBool then
+        S = S==int8(1)
+    end
 endfunction
diff --git a/scilab/modules/elementary_functions/tests/unit_tests/gsort_boolean.tst b/scilab/modules/elementary_functions/tests/unit_tests/gsort_boolean.tst
new file mode 100644 (file)
index 0000000..d018c73
--- /dev/null
@@ -0,0 +1,139 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+//
+// Copyright (C) 2019 - Samuel GOUGEON
+//
+// This file is hereby licensed under the terms of the GNU GPL v2.0,
+// pursuant to article 5.3.4 of the CeCILL v.2.1.
+// This file was originally licensed under the terms of the CeCILL v2.1,
+// and continues to be available under such terms.
+// For more information, see the COPYING file which you should have received
+// along with this program.
+// =============================================================================
+
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+
+// Scalar
+assert_checkequal(gsort(%t), %t);
+assert_checkequal(gsort(%f), %f);
+
+// Vector
+b = [%f %t %f %t ];
+assert_checkequal(gsort(b),  [%t %t %f %f]);
+assert_checkequal(gsort(b'), [%t %t %f %f]');
+assert_checkequal(gsort(b,"g","i"),  [%f %f %t %t]);
+assert_checkequal(gsort(b',"g","i"), [%f %f %t %t]');
+
+assert_checkequal(gsort(b,"r"), b);
+assert_checkequal(gsort(b,"r","i"), b);
+assert_checkequal(gsort(b',"c"),    b');
+assert_checkequal(gsort(b',"c","i"), b');
+
+assert_checkequal(gsort(b,"lr"), b);
+assert_checkequal(gsort(b,"lr","i"), b);
+assert_checkequal(gsort(b',"lc"),    b');
+assert_checkequal(gsort(b',"lc","i"), b');
+
+// Matrix
+b = [%f,%t,%t,%t,%t;%f,%f,%f,%f,%t;%t,%f,%t,%f,%f]; // (3x5)
+assert_checkequal(gsort(b), [%t,%t,%t,%f,%f;%t,%t,%f,%f,%f;%t,%t,%f,%f,%f]);
+assert_checkequal(gsort(b,"g","i"), [%f,%f,%f,%t,%t;%f,%f,%f,%t,%t;%f,%f,%t,%t,%t]);
+
+ref = [%t,%t,%t,%t,%t;%f,%f,%t,%f,%t;%f,%f,%f,%f,%f];
+assert_checkequal(gsort(b,"r"), ref);
+assert_checkequal(gsort(b,"r","i"), ref($:-1:1,:));
+ref = [%t,%t,%t,%t,%f;%t,%f,%f,%f,%f;%t,%t,%f,%f,%f];
+assert_checkequal(gsort(b,"c"), ref);
+assert_checkequal(gsort(b,"c","i"), ref(:,$:-1:1));
+
+ref = [%t,%f,%t,%f,%f;%f,%t,%t,%t,%t;%f,%f,%f,%f,%t];
+assert_checkequal(gsort(b,"lr"), ref);
+assert_checkequal(gsort(b,"lr","i"), ref($:-1:1,:));
+ref = [%t,%t,%t,%t,%f;%t,%f,%f,%f,%f;%f,%t,%f,%f,%t];
+assert_checkequal(gsort(b,"lc"), ref);
+assert_checkequal(gsort(b,"lc","i"), ref(:,$:-1:1));
+
+// Hypermatrix
+b = cat(3,[%f %t %f %t ; %t %t %t %f ; %f %t %f %t], ..
+          [%t %t %f %f ; %t %t %f %f ; %f %t %f %t]);
+s = [3 4 2];
+// "g"
+ref = matrix([%t,%t,%t,%t,%t,%t,%t,%t,%t,%t,%t,%t,%t,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f],s);
+assert_checkequal(gsort(b), ref);
+ref = matrix([%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%t,%t,%t,%t,%t,%t,%t,%t,%t,%t,%t,%t,%t],s);
+assert_checkequal(gsort(b,"g","i"), ref);
+// "r"
+ref = matrix([%t,%f,%f,%t,%t,%t,%t,%f,%f,%t,%t,%f,%t,%t,%f,%t,%t,%t,%f,%f,%f,%t,%f,%f],s);
+assert_checkequal(gsort(b,"r"), ref);
+ref = matrix([%f,%f,%t,%t,%t,%t,%f,%f,%t,%f,%t,%t,%f,%t,%t,%t,%t,%t,%f,%f,%f,%f,%f,%t],s);
+assert_checkequal(gsort(b,"r","i"), ref);
+// "c"
+ref = matrix([%t,%t,%t,%t,%t,%t,%f,%t,%f,%f,%f,%f,%t,%t,%t,%t,%t,%t,%f,%f,%f,%f,%f,%f],s);
+assert_checkequal(gsort(b,"c"), ref);
+ref = matrix([%f,%f,%f,%f,%t,%f,%t,%t,%t,%t,%t,%t,%f,%f,%f,%f,%f,%f,%t,%t,%t,%t,%t,%t],s);
+assert_checkequal(gsort(b,"c","i"), ref);
+// "lr"
+ref = matrix([%t,%f,%f,%t,%t,%t,%t,%f,%f,%f,%t,%t,%t,%t,%f,%t,%t,%t,%f,%f,%f,%f,%f,%t],s);
+assert_checkequal(gsort(b,"lr"), ref);
+ref = matrix([%f,%f,%t,%t,%t,%t,%f,%f,%t,%t,%t,%f,%f,%t,%t,%t,%t,%t,%f,%f,%f,%t,%f,%f],s);
+assert_checkequal(gsort(b,"lr","i"), ref);
+// "lc"
+ref = matrix([%t,%t,%t,%t,%f,%t,%f,%t,%f,%f,%t,%f,%t,%t,%t,%t,%t,%f,%f,%f,%t,%f,%f,%f],s);
+assert_checkequal(gsort(b,"lc"), ref);
+ref = matrix([%f,%t,%f,%f,%t,%f,%t,%f,%t,%t,%t,%t,%f,%f,%f,%f,%f,%t,%t,%t,%f,%t,%t,%t],s);
+assert_checkequal(gsort(b,"lc","i"), ref);
+
+// ========
+// K output
+// ========
+// Matrix
+// ------
+// With some equal rows and cols, to check that initial order is kept
+b = [%f %t %f %t ; %t %t %t %f ; %f %t %f %t];
+// "r"
+[?,k] = gsort(b, "r");
+assert_checkequal(k, [2,1,2,1;1,2,1,3;3,3,3,2]);
+[?,k] = gsort(b, "r", "i");
+assert_checkequal(k, [1,1,1,2;3,2,3,1;2,3,2,3]);
+// "c"
+[?,k] = gsort(b, "c");
+assert_checkequal(k, [2,4,1,3;1,2,3,4;2,4,1,3]);
+[?,k] = gsort(b, "c", "i");
+assert_checkequal(k, [1,3,2,4;4,1,2,3;1,3,2,4]);
+// "lr"
+[?,k] = gsort(b, "lr");
+assert_checkequal(k, [2 1 3]');
+[?,k] = gsort(b, "lr", "i");
+assert_checkequal(k, [1 3 2]');
+// "lc"
+[?,k] = gsort(b, "lc");
+assert_checkequal(k, [2 4 1 3]);
+[?,k] = gsort(b, "lc", "i");
+assert_checkequal(k, [1 3 4 2]);
+
+// Hypermatrix
+// -----------
+b = cat(3,[%f %t %f %t ; %t %t %t %f ; %f %t %f %t], ..
+          [%t %t %f %f ; %t %t %f %f ; %f %t %f %t]);
+s = [3 4 2];
+// "r"
+[?,k] = gsort(b, "r");
+assert_checkequal(k, matrix([2,1,3,1,2,3,2,1,3,1,3,2,1,2,3,1,2,3,1,2,3,3,1,2],s));
+[?,k] = gsort(b, "r", "i");
+assert_checkequal(k, matrix([1,3,2,1,2,3,1,3,2,2,1,3,3,1,2,1,2,3,1,2,3,1,2,3],s));
+// "c"
+[?,k] = gsort(b, "c");
+assert_checkequal(k, matrix([2,1,2,4,2,4,1,3,1,3,4,3,1,1,2,2,2,4,3,3,1,4,4,3],s));
+[?,k] = gsort(b, "c", "i");
+assert_checkequal(k, matrix([1,4,1,3,1,3,2,2,2,4,3,4,3,3,1,4,4,3,1,1,2,2,2,4],s));
+// "lr"
+[?,k] = gsort(b, "lr");
+assert_checkequal(k, cat(3,[2 1 3]', [1 2 3]'));
+[?,k] = gsort(b, "lr", "i");
+assert_checkequal(k, cat(3,[1 3 2]', [3 1 2]') );
+// "lc"
+[?,k] = gsort(b, "lc");
+assert_checkequal(k, cat(3,[2 4 1 3], [2 1 4 3]));
+[?,k] = gsort(b, "lc", "i");
+assert_checkequal(k, cat(3,[1 3 4 2], [3 4 1 2]));