<?xml version="1.0" encoding="UTF-8"?>
<!--
 * Scilab ( https://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) 2008 - INRIA
 * Copyright (C) 2012 - 2016 - Scilab Enterprises
 * 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.
 *
 -->
<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
          xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns5="http://www.w3.org/1999/xhtml"
          xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook"
          xmlns:scilab="http://www.scilab.org" xml:id="perms" xml:lang="en">
    <refnamediv>
        <refname>perms</refname>
        <refpurpose>Generate the table of permutations of given elements</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <title>Syntax</title>
        <synopsis>
            y = perms(x)
            y = perms(x, "unique")
        </synopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Arguments</title>
        <variablelist>
            <varlistentry>
                <term>x</term>
                <listitem>
                    <para>
                        Row or column vector of any data type for which the size(), ==, and []
                        operators are defined, including cells.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>"unique"</term>
                <listitem>
                    <para>
                        Optional text flag, to compute and return the whole set of
                        unique permutations, <emphasis>without any duplicate</emphasis> row.
                        This option can be used only if <varname>x</varname> is sortable.
                        That applies to boolean, integer, real number, and text data types.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>y</term>
                <listitem>
                    <para>
                        Array of the type of x, with n=size(x,"*") columns.
                        Each row provides a permutation. Without using the "unique" option,
                        <varname>y</varname> returns n! rows. Otherwise, the number
                        size(y,1)≤ n! of rows depends on the multiplicities of unique values of x.
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Description</title>
        <para>
            Given a vector <varname>x</varname> of length <literal>n</literal>,
            <literal>perms(..)</literal> computes the expected number of permutations,
            and checks if there is enough available memory to compute and store them as the result.
        </para>
        <para>
            If there is not enough memory, nothing else is done and an error is generated.
        </para>
        <para>
            Otherwise, the permutations are computed and returned.
        </para>
        <note>
            When "unique" is used,
            <itemizedlist>
                <listitem>
                    if no duplicate is detected in <varname>x</varname>, the computations are done
                    as without "unique", that is faster.
                </listitem>
                <listitem>
                    <varname>x</varname> is first sorted in ascending direction, and
                    <varname>y</varname> is built in ascending lexicographic order.
                </listitem>
            </itemizedlist>
            Otherwise : The initial order of <varname>x</varname> components is kept, and the order
            of permutations in <varname>y</varname> takes it into account. Thus, if necessary,
            <varname>x</varname> can be sorted according to the order <emphasis>chosen by the user,
            before</emphasis> calling <literal>perms()</literal>.
        </note>
        <warning>
            As a reminder, here is the weight <varname>n*n!*8</varname> of <varname>y</varname>
            in bytes, vs the length <literal>n</literal> of <varname>x</varname>,
            if <varname>x</varname> are decimal numbers and "unique" is not used:
        </warning>
        <para>
            <table border="1">
                <tr align="center">
                    <th>n</th>
                    <td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td>
                    <td>9</td><td>10</td><td>11</td><td>12</td><td>13</td>
                </tr>
                <tr>
                    <th>y [bytes]</th>
                    <td>32</td><td>144</td><td>768</td><td>4800</td><td>34560</td><td>288240</td>
                    <td>2.58×10<superscript>6</superscript></td>
                    <td>26.1×10<superscript>6</superscript></td>
                    <td>290×10<superscript>6</superscript></td>
                    <td>3.51×10<superscript>9</superscript></td>
                    <td>46.0×10<superscript>9</superscript></td>
                    <td>648×10<superscript>9</superscript></td>
                </tr>
            </table>
        </para>
    </refsection>
    <refsection>
        <title>Examples</title>
        <programlisting role="example"><![CDATA[
x = [4, 7, 10];
y = perms(x)

x = ["a" "b" "c" "d"];
y = perms(x)'

c = {"bonjour", %pi, %t};
perms(c)
 ]]></programlisting>
    <screen><![CDATA[
--> x = [4, 7, 10];
--> y = perms(x)
 y  =
   10.   7.    4.
   10.   4.    7.
   7.    10.   4.
   7.    4.    10.
   4.    10.   7.
   4.    7.    10.

--> x = ["a" "b" "c" "d"];
--> perms(x)'
 ans  =
!d  d  d  d  d  d  c  c  c  c  c  c  b  b  b  b  b  b  a  a  a  a  a  a  !
!c  c  b  b  a  a  d  d  b  b  a  a  d  d  c  c  a  a  d  d  c  c  b  b  !
!b  a  c  a  c  b  b  a  d  a  d  b  c  a  d  a  d  c  c  b  d  b  d  c  !
!a  b  a  c  b  c  a  b  a  d  b  d  a  c  a  d  c  d  b  c  b  d  c  d  !

--> c = {"bonjour", %pi, %t};
--> perms(c)
 ans  =
  [1x1 boolean ]  [1x1 constant]  [1x1 string  ]
  [1x1 boolean ]  [1x1 string  ]  [1x1 constant]
  [1x1 constant]  [1x1 boolean ]  [1x1 string  ]
  [1x1 constant]  [1x1 string  ]  [1x1 boolean ]
  [1x1 string  ]  [1x1 boolean ]  [1x1 constant]
  [1x1 string  ]  [1x1 constant]  [1x1 boolean ]
]]></screen>
    <para>
        With duplicate elements:
    </para>
    <programlisting role="example"><![CDATA[
perms([1 0 0])
perms([1 0 0], "unique")
perms([0 1 2 0], "unique")'
p = perms([0 0 0 0 1 1 1 2 2 3], "unique");
size(p)
 ]]></programlisting>
    <screen><![CDATA[
--> perms([1 0 0])
 ans  =
   0.   0.   1.
   0.   1.   0.
   0.   0.   1.
   0.   1.   0.
   1.   0.   0.
   1.   0.   0.

--> perms([1 0 0], "unique")
 ans  =
   0.   0.   1.
   0.   1.   0.
   1.   0.   0.

--> perms([0 1 2 0], "unique")'
 ans  =
   0.   0.   0.   0.   0.   0.   1.   1.   1.   2.   2.   2.
   0.   0.   1.   1.   2.   2.   0.   0.   2.   0.   0.   1.
   1.   2.   0.   2.   0.   1.   0.   2.   0.   0.   1.   0.
   2.   1.   2.   0.   1.   0.   2.   0.   0.   1.   0.   0.

--> p = perms([0 0 0 0 1 1 1 2 2 3], "unique");
--> size(p)
 ans  =
   12600.   10.  // instead of 10! = 3628800 rows
]]></screen>
    </refsection>
    <refsection role="see also">
        <title>See Also</title>
        <simplelist type="inline">
            <member>
                <link linkend="grand">grand(x,'prm')</link>
            </member>
            <member>
                <link linkend="factorial">factorial</link>
            </member>
            <member>
                <link linkend="unique">unique</link>
            </member>
            <member>
                <link linkend="gsort">gsort</link>
            </member>
            <member>
                <link linkend="try">try</link>
            </member>
        </simplelist>
    </refsection>
    <refsection role="history">
        <title>History</title>
        <revhistory>
            <revision>
                <revnumber>6.1.0</revnumber>
                <revdescription>
                    "unique" option introduced.
                </revdescription>
            </revision>
        </revhistory>
    </refsection>
</refentry>
