* Bugs 15838 15839 15842 16452 16454 fixed: gsort() for all sparse in all modes
[scilab.git] / scilab / modules / elementary_functions / help / en_US / searchandsort / gsort.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4  * Copyright (C) 2008 - INRIA
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  * Copyright (C) 2018 - 2020 - Samuel GOUGEON
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  -->
16 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
17           xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns5="http://www.w3.org/1999/xhtml"
18           xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook"
19           xmlns:scilab="http://www.scilab.org" xml:id="gsort" xml:lang="en">
20     <refnamediv>
21         <refname>gsort</refname>
22         <refpurpose>sorts boolean, numerical and text arrays</refpurpose>
23     </refnamediv>
24     <refsynopsisdiv>
25         <title>Syntax</title>
26         <synopsis>
27             B = gsort(A)
28             B = gsort(A, method)
29             B = gsort(A, method, direction)
30             B = gsort(A, method, directions, rankFuncs)
31             [B, k] = gsort(..)
32         </synopsis>
33     </refsynopsisdiv>
34     <refsection>
35         <title>Arguments</title>
36         <variablelist>
37             <varlistentry>
38                 <term>A</term>
39                 <listitem>
40                     Scalar, vector, matrix or hypermatrix of booleans, integers, real or
41                     complex numbers, or text. Sparse matrices of real numbers,
42                     of complex numbers, or of booleans can also be sorted.
43                     <note>
44                         Overloading for unhandled types is allowed.
45                     </note>
46                     <para/>
47                 </listitem>
48             </varlistentry>
49             <varlistentry>
50                 <term>method</term>
51                 <listitem>
52                     A keyword: The sorting method:
53                     <informaltable>
54                         <tr valign="top">
55                             <th>'g'</th><td>:</td>
56                             <td>General sorting: All elements of <literal>A</literal> are sorted
57                                 (default method).
58                             </td>
59                         </tr>
60                         <tr valign="top">
61                             <th>'r'</th><td>:</td>
62                             <td>Rows of each column of <literal>A</literal> are sorted.</td>
63                         </tr>
64                         <tr valign="top">
65                             <th>'c'</th><td>:</td>
66                             <td>Columns of each row of <literal>A</literal> are sorted.</td>
67                         </tr>
68                         <tr valign="top"><th>'lr'</th><td>:</td>
69                             <td>lexicographic sort of the rows of <literal>A</literal>:
70                                 Sorts rows according to values in the first column. If a group of
71                                 sorted rows have the same value in column #1, resorts the group
72                                 according to values in column #2. etc.
73                                 Not applicable to hypermatrices.
74                             </td>
75                         </tr>
76                         <tr valign="top"><th>'lc'</th><td>:</td>
77                             <td>lexicographic sort of the columns of <literal>A</literal>
78                                 (not for hypermatrices).
79                             </td>
80                         </tr>
81                     </informaltable>
82                     <para/>
83                 </listitem>
84             </varlistentry>
85             <varlistentry>
86                 <term>direction</term>
87                 <listitem>
88                     "d" for <emphasis role="bold">d</emphasis>ecreasing order (default), or
89                     "i" for <emphasis role="bold">i</emphasis>ncreasing one.
90                     <para/>
91                 </listitem>
92             </varlistentry>
93             <varlistentry>
94                 <term>directions</term>
95                 <listitem>
96                     vector of "i" and "d" characters, with as many elements than
97                     <varname>rankFuncs</varname> has.
98                     <literal>directions(k)</literal> is used for <varname>rankFuncs(k)</varname>.
99                     <para/>
100                 </listitem>
101             </varlistentry>
102             <varlistentry>
103                 <term>rankFuncs</term>
104                 <listitem>
105                     list() whose elements are among the following type:
106                     <itemizedlist>
107                         <listitem>
108                             identifier <literal>fun</literal> of a function in Scilab language
109                             or of a builtin function.
110                         </listitem>
111                         <listitem>
112                             : colon. It stands for a <literal>fun</literal> such that
113                             <literal>fun(A)</literal> returns <literal>A</literal>.
114                         </listitem>
115                         <listitem>
116                             a <literal>list(fun, param1, param2,..)</literal> where
117                             <itemizedlist>
118                                 <listitem>
119                                     <literal>fun</literal> is the identifier of a Scilab or
120                                     builtin function.
121                                 </listitem>
122                                 <listitem>
123                                     <literal>param1, param2,..</literal> are parameters.
124                                 </listitem>
125                             </itemizedlist>
126                             such that <literal>fun(A, param1, param2, ..)</literal> will be called.
127                         </listitem>
128                     </itemizedlist>
129                     <para>
130                         The functions <literal>fun</literal> must fullfill the following conditions:
131                         <itemizedlist>
132                             <listitem>
133                                 <literal>R=fun(A)</literal> or <literal>R=fun(A, param1, param2,..)</literal>
134                                 must be supported.
135                             </listitem>
136                             <listitem>
137                                 <literal>fun</literal> must work in an element-wise way, meaning:
138                                 <literal>size(R)==size(A)</literal>, and <literal>R(k)</literal>
139                                 is about only <literal>A(k)</literal>
140                             </listitem>
141                             <listitem>
142                                 <literal>R</literal> must be of simple sortable type: boolean,
143                                 integer, real, text.
144                             </listitem>
145                         </itemizedlist>
146                     </para>
147                     <para>
148                         <note>
149                             When <literal>A</literal> are complex numbers, the usual functions
150                             <literal>real, imag, abs, atan</literal> can be specified. Then,
151                             <literal>atan(imag(A),real(A))</literal> will be called instead of
152                             <literal>atan(A)</literal>.
153                         </note>
154                     </para>
155                 </listitem>
156             </varlistentry>
157             <varlistentry>
158                 <term>B</term>
159                 <listitem>
160                     The sorted array, with  <literal>A</literal>'s data type, encoding, and sizes.
161                     <para/>
162                 </listitem>
163             </varlistentry>
164             <varlistentry>
165                 <term>k</term>
166                 <listitem>
167                     Array of decimal integers, of size <literal>size(A)</literal>:
168                     Initial indices of <literal>B</literal> elements, in <literal>A</literal>.
169                     If <literal>A</literal> is a matrix, according to the chosen method,
170                     <table>
171                     <tr>
172                         <th valign="top">"g"</th><td>:</td>
173                         <td>
174                             <literal>k</literal> is a matrix of size(A): <literal>k(i)</literal>
175                             is the linear index
176                             of <literal>B(i)</literal> in <literal>A</literal>, such that
177                             <literal>B(:) = A(k)</literal>.
178                         </td>
179                     </tr>
180                     <tr>
181                         <th valign="top">"r"</th><td>:</td>
182                         <td>
183                             <literal>k</literal> is a matrix of size(A): <literal>k(i,j)</literal>
184                             is the <literal>1 ≤ index ≤ size(A,1)</literal>
185                             of <literal>B(i,j)</literal> in the column <literal>A(:,j)</literal>.
186                         </td>
187                     </tr>
188                     <tr>
189                         <th valign="top">"c"</th><td>:</td>
190                         <td>
191                             <literal>k</literal> is a matrix of size(A): <literal>k(i,j)</literal>
192                             is the <literal>1 ≤ index ≤ size(A,2)</literal>
193                             of <literal>B(i,j)</literal> in the row <literal>A(i,:)</literal>.
194                         </td>
195                     </tr>
196                     <tr>
197                         <th valign="top">"lr"</th><td>:</td>
198                         <td>
199                             <literal>k</literal> is a column of size(A,1), such that
200                             <literal>B = A(k,:)</literal>.
201                         </td>
202                     </tr>
203                     <tr>
204                         <th valign="top">"lc"</th><td>:</td>
205                         <td>
206                             <literal>k</literal> is a row of size(A,2), such that
207                             <literal>B = A(:,k)</literal>.
208                         </td>
209                     </tr>
210                     </table>
211                     <para/>
212                 </listitem>
213             </varlistentry>
214         </variablelist>
215     </refsection>
216     <refsection>
217         <title>Description</title>
218         <para>
219             <literal>gsort</literal> performs a "quick sort" for various native data types.
220             By default, sorting is performed in decreasing order.
221         </para>
222         <para>
223             <literal>%nan</literal> values are considered greater than <literal>%inf</literal>.
224         </para>
225         <para>
226             Complex numbers are by default sorted only according to their moduli.
227             Complete sorting can be achieved using the multilevel mode, through the
228             <varname>rankFuncs</varname> and <varname>directions</varname> arguments.
229             Example:
230         </para>
231         <para>
232             <literal>M = gsort(C, "g", ["i" "d"], list(real, imag))</literal><para/>
233             will sort the array C, first by increasing real parts, and for elements
234             of equal real parts, second by decreasing imaginary parts.
235             The multilevel mode is described with details in a dedicated subsection below.
236         </para>
237         <para>
238             Texts are sorted in alphabetical order, in a case-sensitive way.
239             Extended UTF characters are supported.
240         </para>
241         <para>
242             Sorting boolean arrays is mostly useful with the "r", "c", "lr" or "lc" methods.
243         </para>
244         <para>
245             <note>
246                 Whatever is the chosen method, <emphasis role="bold">the algorithm preserves the
247                 relative order of elements with equal values.
248             </emphasis>
249             </note>
250         </para>
251         <refsect3>
252             <title>Sorting methods</title>
253             <para>
254                 <emphasis role="bold">B = gsort(A,'g', ..)</emphasis> sorts all elements of
255                 <varname>A</varname>, and stores sorted elements in the first column from top to
256                 bottom, then in the second column, etc.
257             </para>
258             <para>
259                 <emphasis role="bold">B = gsort(A,'c', ..)</emphasis> sorts each row of A.
260                 Each sorted element is on the same row as in A, but possibly on another column
261                 corresponding to its sorting rank on the row.
262             </para>
263             <para>
264                 <emphasis role="bold">B = gsort(A,'r', ..)</emphasis> sorts each column of A.
265                 Each sorted element is on the same column as in A, but possibly on another row
266                 corresponding to its sorting rank.
267             </para>
268             <para>
269                 <emphasis role="bold">B = gsort(A,'lr', ..)</emphasis> sorts rows of A, as a whole,
270                 in a lexical way. Two rows are compared and sorted in the following way:
271                 The elements of their first column are compared. If their ranks are not equal,
272                 both rows are sorted accordingly. Otherwise, the elements of their second column
273                 are compared. etc... up to the last column if it is required.
274             </para>
275             <para>
276                 <emphasis role="bold">B = gsort(A,'lc', ..)</emphasis> sorts columns of A,
277                 as a whole, in a lexical way (see above).
278             </para>
279         </refsect3>
280         <refsect3>
281             <title>Multilevel sorting</title>
282             <para>
283                 As noted above, when two compared elements have equal ranks, their initial relative
284                 order in <literal>A</literal> is preserved in the result <literal>B</literal> .
285             </para>
286             <para>
287                 However, in many cases, going beyond through a multi-level sorting can be useful
288                 and required:
289                 After the first sort performed according to a first criterion and sorting
290                 direction, it is possible to define a second criterion and sorting
291                 direction and apply them to 1st-rank-equal elements gathered by the first sort.
292             </para>
293             <para>
294                 If after the two first sorting some elements have still the same ranks, it is
295                 possible to define and use a 3rd sorting level, etc.
296             </para>
297             <para>
298                 <emphasis role="bold">Applied examples</emphasis> (see also the Examples section):
299                 <orderedlist>
300                     <listitem>
301                         <emphasis>Sorting a matrix C of complex numbers,
302                         first: by increasing modulus, second: by increasing phase</emphasis>:
303                         <para/>
304                         <literal>gsort(C, "g", ["i" "i"], list(abs, atan))</literal>
305                         <para/>
306                     </listitem>
307                     <listitem>
308                         <emphasis>Sorting the columns of a matrix T of texts,
309                         first: by increasing length, second: in anti-alphabetical order</emphasis>:
310                         <para/>
311                         <literal>gsort(T, "c", ["i" "d"], list(length, :))</literal>
312                         <para/>
313                     </listitem>
314                     <listitem>
315                         <emphasis>Sorting a matrix P of polynomials,
316                         first: by increasing degree, second: by decreasing value of the constant
317                         0-degree coefficient</emphasis>:
318                         <screen>
319 function c = get_coef(p, i)
320     // i: degree of the coeff to return
321     c = matrix(coeff(p(:))(:,i+1), size(p))
322 endfunction
323
324 gsort(P, "c", ["i" "d"], list(degree, list(get_coef,0)))
325 </screen>
326                         In this example, the second ranking function allows to specify the degree i
327                         of the coefficient to be considered as secondary sorting value.
328                         <para/>
329                     </listitem>
330                     <listitem>
331                         <emphasis>Sorting a matrix D of decimal numbers,
332                         first: by increasing integer parts, second: by decreasing fractional parts</emphasis>:
333                         <screen>
334 function r = get_frac(numbers)
335     r = numbers - int(numbers)
336 endfunction
337
338 gsort(D, "g", ["i" "d"], list(int, get_frac))
339 </screen>
340                     </listitem>
341                     <para/>
342                 </orderedlist>
343             </para>
344         </refsect3>
345     </refsection>
346     <refsection>
347         <title>Examples</title>
348         <para>
349             Sorting elements in rows:
350         </para>
351         <para>
352         <programlisting role="example"><![CDATA[
353 m = [ 0.  2.  1.  2.  1.  0.
354       1.  1.  3.  1.  0.  3.
355       2.  3   3.  2.  1.  1. ];
356
357 [s, k] = gsort(m, "c")
358 ]]>     </programlisting>
359         <screen><![CDATA[
360 --> [s, k] = gsort(m, "c")
361  s  =
362    2.   2.   1.   1.   0.   0.
363    3.   3.   1.   1.   1.   0.
364    3.   3.   2.   2.   1.   1.
365
366  k  =
367    2.   4.   3.   5.   1.   6.
368    3.   6.   1.   2.   4.   5.
369    2.   3.   1.   4.   5.   6.
370 ]]></screen>
371         </para>
372         <para>
373             Lexicographic sorting of rows:
374         </para>
375         <para>
376         <programlisting role="example"><![CDATA[
377 v = ['Scilab' '3.1'
378      'xcos'   '4.0'
379      'xcos'   '3.1'
380      'Scilab' '2.7'
381      'xcos'   '2.7'
382      'Scilab' '4.0'];
383
384 [s, k] = gsort(v,'lr','i'); s, k'
385 ]]>     </programlisting>
386             <screen><![CDATA[
387 --> [s, k] = gsort(v,'lr','i'); s, k'
388  s  =
389   "Scilab"  "2.7"
390   "Scilab"  "3.1"
391   "Scilab"  "4.0"
392   "xcos"    "2.7"
393   "xcos"    "3.1"
394   "xcos"    "4.0"
395
396  ans  =
397    4.   1.   6.   5.   3.   2.
398 ]]></screen>
399         </para>
400         <para>
401             Lexicographic sorting of boolean columns:
402         </para>
403         <para>
404         <programlisting role="example"><![CDATA[
405 m  = [ 0 1 0 1 1 1 0 1
406        0 0 1 1 1 1 0 0
407        0 0 1 1 0 0 0 0 ]==1;
408 m
409 [s, k] = gsort(m, "lc")  // sorting columns in decreasing order
410 ]]>     </programlisting>
411         <screen><![CDATA[
412 --> m
413  m  =
414   F T F T T T F T
415   F F T T T T F F
416   F F T T F F F F
417
418 --> [s, k] = gsort(m, "lc")
419  s  =
420   T T T T T F F F
421   T T T F F T F F
422   T F F F F T F F
423
424  k  =
425    4.   5.   6.   2.   8.   3.   1.   7.
426 ]]></screen>
427         </para>
428     <refsect3>
429         <title>Multilevel sorting</title>
430         <para>
431             <emphasis role="bold">With some decimal numbers</emphasis>:
432             Sorting first: by increasing integer parts,
433             second: by decreasing fractional parts.
434         </para>
435         <para>
436         <programlisting role="example"><![CDATA[
437 // Function getting the fractional parts
438 function r = get_frac(d)
439     r = d - int(d)
440 endfunction
441
442 // Unsorted data
443 d = [
444    2.1   0.1   1.3   1.2   0.1   1.2
445    0.3   1.2   2.3   0.3   1.2   2.1
446    0.1   1.2   1.1   1.2   2.2   1.1
447    2.3   1.3   0.1   2.3   0.1   0.1
448    0.1   2.2   2.1   0.2   1.1   0.3
449   ];
450 // Sorting
451 [r, k] = gsort(d, "g", ["i" "d"], list(int, get_frac))
452 ]]>     </programlisting>
453         <screen><![CDATA[
454  r  =
455    0.3   0.1   0.1   1.2   1.1   2.2
456    0.3   0.1   1.3   1.2   1.1   2.2
457    0.3   0.1   1.3   1.2   2.3   2.1
458    0.2   0.1   1.2   1.2   2.3   2.1
459    0.1   0.1   1.2   1.1   2.3   2.1
460
461  k  =
462    2.    5.    29.   16.   25.   10.
463    17.   6.    9.    18.   28.   23.
464    30.   14.   11.   22.   4.    1.
465    20.   21.   7.    26.   12.   15.
466    3.    24.   8.    13.   19.   27.
467 ]]></screen>
468         </para>
469         <para>
470             <emphasis role="bold">With complex numbers</emphasis>:
471             Sorting, first: by increasing real parts, second: by increasing imaginary parts.
472         </para>
473         <para>
474         <programlisting role="example"><![CDATA[
475 //c = [-1 1 ; -1 0; 0 2; 0 %nan; 0 -1; 0 %inf ; 0 1; 1 %nan ; 1 1; 1 -1 ; -1 %nan ; 1 -%inf]
476 //c = matrix(squeeze(grand(1,"prm",complex(c(:,1), c(:,2)))), [3,4])
477 s = "complex([0,0,-1,-1;0,-1,1,1;1,1,0,0]," + ..
478             "[%inf,2,%nan,1;-1,0,-1,%nan;1,-%inf,1,%nan])";
479 c = evstr(s)
480 [r, k] = gsort(c, "g", ["i" "i"], list(real, imag))
481 ]]>     </programlisting>
482     <screen><![CDATA[
483 --> c = evstr(s)
484  c  =
485    0. + Infi   0. + 2.i   -1. + Nani  -1. + i
486    0. - i     -1. + 0.i    1. - i      1. + Nani
487    1. + i      1. - Infi   0. + i      0. + Nani
488
489  r  =
490   -1. + 0.i    0. - i     0. + Infi   1. - i
491   -1. + i      0. + i     0. + Nani   1. + i
492   -1. + Nani   0. + 2.i   1. - Infi   1. + Nani
493
494  k  =
495    5.    2.   1.    8.
496    10.   9.   12.   3.
497    7.    4.   6.    11.
498 ]]></screen>
499         </para>
500         <para>
501             <emphasis role="bold">With some texts:</emphasis>
502             Sorting rows in columns, first by increasing lengths, second by alphabetical order
503         </para>
504         <para>
505         <programlisting role="example"><![CDATA[
506 t = [
507   "cc"    "ca"    "ab"    "bbca"  "b"     "ccbc"  "aab"   "bca"
508   "ac"    "bba"   "aba"   "bb"    "a"     "cac"   "b"     "b"
509   "aaaa"  "ac"    "b"     "bbca"  "bb"    "bc"    "aa"    "ca"
510   "c"     "ba"    "cbb"   "a"     "aab"   "abbb"  "ac"    "c"
511   "cbb"   "b"     "cabb"  "bccc"  "aba"   "acb"   "acb"   "b"
512   "cba"   "cc"    "a"     "abbb"  "ab"    "cc"    "bba"   "caaa"
513   ];
514
515 [r, k] = gsort(t, "r", ["i" "i"], list(length, :))
516 ]]>     </programlisting>
517         <screen><![CDATA[
518 --> [r, k] = gsort(t, "r", ["i" "i"], list(length, :))
519  r  =
520   "c"     "b"    "a"     "a"     "a"    "bc"    "b"    "b"
521   "ac"    "ac"   "b"     "bb"    "b"    "cc"    "aa"   "b"
522   "cc"    "ba"   "ab"    "abbb"  "ab"   "acb"   "ac"   "c"
523   "cba"   "ca"   "aba"   "bbca"  "bb"   "cac"   "aab"  "ca"
524   "cbb"   "cc"   "cbb"   "bbca"  "aab"  "abbb"  "acb"  "bca"
525   "aaaa"  "bba"  "cabb"  "bccc"  "aba"  "ccbc"  "bba"  "caaa"
526
527  k  =
528    4.   5.   6.   4.   2.   3.   2.   2.
529    2.   3.   3.   2.   1.   6.   3.   5.
530    1.   4.   1.   6.   6.   5.   4.   4.
531    6.   1.   2.   1.   3.   2.   1.   3.
532    5.   6.   4.   3.   4.   4.   5.   1.
533    3.   2.   5.   5.   5.   1.   6.   6.
534 ]]></screen>
535         </para>
536 <!--  Display up to 6.0.2 (without extra blank lines)
537  r  =
538 !c     b    a     a     a    bc    b    b     !
539 !ac    ac   b     bb    b    cc    aa   b     !
540 !cc    ba   ab    abbb  ab   acb   ac   c     !
541 !cba   ca   aba   bbca  bb   cac   aab  ca    !
542 !cbb   cc   cbb   bbca  aab  abbb  acb  bca   !
543 !aaaa  bba  cabb  bccc  aba  ccbc  bba  caaa  !
544 -->
545         <para>
546             <emphasis role="bold">With some polynomials:</emphasis>
547             Sorting first: by decreasing values of x^0, second: by increasing degrees.
548         </para>
549         <para>
550         <programlisting role="example"><![CDATA[
551 function c = get_coef(p, d)
552     // d : degree of the coeffs to return
553     c = matrix(coeff(p(:))(:,d+1), size(p))
554 endfunction
555
556 P = ["[-x,1-2*x,2+2*x,1-x,2,-1-x;"
557      "1-x,-1+x,-1,x,1+2*x,2*x;"
558      "-2+x,1,-2,2+x,-x,-1-x]"];
559
560 x = varn(%s,"x");
561 P = evstr(P)
562
563 [r, k] = gsort(P, "g", ["d" "i"], list(list(get_coef, 0), degree))
564 ]]>     </programlisting>
565         <screen><![CDATA[
566 --> P = evstr(P)
567  P  =
568   -x      1 -2x   2 +2x   1 -x   2      -1 -x
569    1 -x  -1 +x   -1       x      1 +2x   2x
570   -2 +x   1      -2       2 +x   -x     -1 -x
571
572 --> [r, k] = gsort(P, "g", ["d" "i"], list(list(get_coef, 0), degree))
573  r  =
574   2      1      1 -x   x   -1     -1 -x
575   2 +2x  1 -x   1 +2x  -x  -1 +x  -2
576   2 +x   1 -2x  -x     2x  -1 -x  -2 +x
577
578  k  =
579    13.   6.   10.   11.   8.    18.
580    7.    2.   14.   15.   5.    9.
581    12.   4.   1.    17.   16.   3.
582 ]]></screen>
583         </para>
584     </refsect3>
585     </refsection>
586     <refsection role="see also">
587         <title>See also</title>
588         <simplelist type="inline">
589             <member>
590                 <link linkend="comparison">comparison</link>
591             </member>
592             <member>
593                 <link linkend="strcmp">strcmp</link>
594             </member>
595             <member>
596                 <link linkend="find">find</link>
597             </member>
598             <member>
599                 <link linkend="overloading">overloading</link>
600             </member>
601         </simplelist>
602     </refsection>
603     <refsection>
604         <title>Bibliography</title>
605         <para>Quick sort algorithm from Bentley &amp; McIlroy's "Engineering a
606             Sort Function". Software---Practice and Experience,
607             23(11):1249-1265
608         </para>
609     </refsection>
610     <refsection>
611         <title>History</title>
612         <revhistory>
613             <revision>
614                 <revnumber>5.4.0</revnumber>
615                 <revremark>
616                     gsort() can now be overloaded for unmanaged types.
617                 </revremark>
618             </revision>
619             <revision>
620                 <revnumber>6.1.0</revnumber>
621                 <revremark>
622                     <itemizedlist>
623                         <listitem>
624                             Booleans can now be sorted.
625                         </listitem>
626                         <listitem>
627                             Multilevel sorting added with the rankFuncs option.
628                             Complete sorting of complex numbers is now possible.
629                         </listitem>
630                     </itemizedlist>
631                 </revremark>
632             </revision>
633             <revision>
634                 <revnumber>6.1.1</revnumber>
635                 <revremark>
636                     gsort() was formerly limited to real or complex vectors,
637                     and only to the `g` method. It is now fully enabled for sparse
638                     vectors and 2D matrices of booleans, real or complex numbers,
639                     in all `g, r, c, lr, lc` methods. Multi-level sorting is
640                     enabled for all types of sparse input.
641                 </revremark>
642             </revision>
643         </revhistory>
644     </refsection>
645 </refentry>