<?xml version="1.0" encoding="UTF-8"?>
<!--
 * Scilab ( https://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) 2008 - INRIA
 * Copyright (C) 2011 - DIGITEO - Michael Baudin
 *
 * Copyright (C) 2012 - 2016 - Scilab Enterprises
 *
 * 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="rand" xml:lang="en">
    <refnamediv>
        <refname>rand</refname>
        <refpurpose>Random numbers</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <title>Syntax</title>
        <synopsis>
            r = rand()
            r = rand(m1,m2,...)
            r = rand(m1,m2,...,key)
            r = rand(x)
            r = rand(x,key)

            s = rand("seed")
            rand("seed",s)

            rand(key)
            key = rand("info")
        </synopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Arguments</title>
        <variablelist>
            <varlistentry>
                <term>m1, m2, ...</term>
                <listitem>
                    <para>
                        integers, the size of the random matrix <literal>r</literal>.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>key</term>
                <listitem>
                    <para>
                        a string, the distribution of random numbers (default  <literal>key="uniform" </literal>).
                        The possible values are:
                        <itemizedlist>
                        <listitem>
                        <literal>"uniform"</literal> or <literal>"u"</literal>
                        </listitem>
                        <listitem>
                        <literal>"normal"</literal> or <literal>"n"</literal>
                        </listitem>
                        </itemizedlist>
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>x</term>
                <listitem>
                    <para>
                        a real or complex matrix.
                        Only its real or complex content and its dimensions are taken into account.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>r</term>
                <listitem>
                    <para>
                        a m1-by-m2-by-... real array of doubles with random entries.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>s</term>
                <listitem>
                    <para>
                        a positive integer: the seed (default <literal>s=0</literal>).
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Description</title>
        <para>
            The purpose of this function is to return a matrix of doubles with real or complex
            random entries.
            Depending on the input arguments, the function can return a random matrix of doubles,
            or can get or set the distribution of random numbers, or can get or set the seed of
            the random number generator.
        </para>
    </refsection>
    <refsection>
        <title>Generate random numbers</title>
        <variablelist>
            <varlistentry>
                <term>r=rand()</term>
                <listitem>
                    <para>returns a 1-by-1 matrix of doubles, with one random value.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>r=rand(m1,m2)</term>
                <listitem>
                    <para>
                        is a random matrix with dimension <literal>m1</literal>-by-
                        <literal>m2</literal>.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>r=rand(m1,m2,...,mn)</term>
                <listitem>
                    <para>
                        returns a random matrix with dimension <literal>m1</literal>-by-
                        <literal>m2</literal>-by-... -by-<literal>mn</literal>.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>r=rand(a)</term>
                <listitem>
                    <para>
                        returns a random matrix with the same size as a.
                        The matrix <literal>r</literal> is real if <literal>a</literal> is a
                        real matrix and <literal>r</literal> is complex if <literal>a</literal> is a
                        complex matrix.
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Change the distribution of the random numbers</title>
        <para>
            The <literal>key</literal> input argument sets the distribution of the
            generated random numbers.
        </para>
        <variablelist>
            <varlistentry>
                <term>rand("uniform") or rand("u")</term>
                <listitem>
                    <para>
                        sets the generator to a uniform random number
                        generator. Random numbers are uniformly distributed in the interval
                        [0,1).
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>rand("normal") or rand("n")</term>
                <listitem>
                    <para>
                        sets the generator to a normal (Gauss-Laplace) random number generator,
                        with mean 0 and variance 1.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>key=rand("info")</term>
                <listitem>
                    <para>
                        return the current distribution of the random generator ("uniform" or
                        "normal")
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Get or set the seed</title>
        <para>
            It is possible to get or set the seed of the random number generator.
        </para>
        <variablelist>
            <varlistentry>
                <term>s=rand("seed")</term>
                <listitem>
                    <para>returns the current value of the seed.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>rand("seed",s)</term>
                <listitem>
                    <para>
                        sets the seed to <literal>s</literal> (by default
                        <literal>s=0</literal> at first call).
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Examples</title>
        <para>
            In the following example, we generate random doubles with
            various distributions.
        </para>
        <programlisting role="example"><![CDATA[
// Get one random double (based on the current distribution)
r=rand()
// Get one 4-by-6 matrix of doubles (based on the current distribution)
r=rand(4,6)
// Get one 4-by-6 matrix of doubles with uniform entries
r=rand(4,6,"uniform")
// Produce a matrix of random doubles with the same size as x
x=rand(4,4);
r=rand(x,"normal")
// Produce a 2-by-2-by-2 array of random doubles
r=rand(2,2,2)
 ]]></programlisting>
        <para>
            In the following example, we change the distribution of the
            number generated by <literal>rand</literal>.
            We first produce normal numbers, then numbers uniform in [0,1).
        </para>
        <programlisting role="example"><![CDATA[
    // Set the rand generator to normal
    rand("normal")
    r=rand(4,6)
    // Get the current distribution
    key=rand("info")
    // Set the rand generator to uniform
    rand("uniform")
    r=rand(4,6)
    key=rand("info")
    ]]></programlisting>
        <para>
            In the following example, we generate a 2-by-3 complex matrix
            of doubles, with normal distribution.
        </para>
        <programlisting role="example"><![CDATA[
    // Produce a 2-by-3 matrix of random complex doubles
    x=rand(2,3)+%i*rand(2,3)
    // Produce a matrix of random complex doubles with
    // normal entries and the same size as x
    r=rand(x,"normal")
    ]]></programlisting>
        <para>
            In the following example, we plot the distribution of uniform
            numbers produced by <literal>rand</literal>.
        </para>
        <programlisting role="example"><![CDATA[
    r=rand(1000,1,"uniform");
    scf();
    histplot(10,r);
    xtitle("Uniform numbers from rand","X","Frequency")
    ]]></programlisting>
        <para>
            In the following example, we plot the distribution of standard normal
            numbers produced by <literal>rand</literal>.
        </para>
        <programlisting role="example"><![CDATA[
    r=rand(1000,1,"normal");
    scf();
    histplot(10,r);
    xtitle("Normal numbers from rand","X","Frequency")
    ]]></programlisting>
    </refsection>
    <refsection>
        <title>Get predictable or less predictable numbers</title>
        <para>
            The "uniform" pseudo random number generator is a deterministic sequence which aims at
            reproducing a independent identically distributed numbers uniform in the
            interval [0,1).
        </para>
        <para>
            In order to get reproducible simulations, the initial seed of the generator is
            zero, such that the sequence will remain the same from a session to the other.
            In other words, the first numbers produced by <literal>rand()</literal> always are : 0.2113249,  0.7560439, ...
        </para>
        <para>
            In some situations, we may want to initialize the seed of the generator in
            order to produce less predictable sequences. In this case, we may initialize the
            seed with the output of the <literal>getdate</literal> function:
        </para>
        <programlisting role="example"><![CDATA[
n=getdate("s");
rand("seed",n);
 ]]></programlisting>
    </refsection>
    <refsection>
        <title>The generator</title>
        <para>
            The <literal>"uniform"</literal> random number generator is described in
            "Urand, A Universal Random Number Generator" by
            Michael A. Malcolm, Cleve B. Moler, Stan-Cs-73-334, January 1973, Computer
            Science Department, School Of Humanities And Sciences, Stanford University.
        </para>
        <para>
            It is a linear congruential generator of the form :
        </para>
        <para>
             x = (a x + c) mod M
        </para>
        <para>
            where the constants are
          <table border="0" cellpadding="0">
             <tr><td>a = 843314861</td></tr>
             <tr><td>c = 453816693</td></tr>
             <tr><td>M = 2<superscript>31</superscript></td></tr>
          </table>
       </para>
        <para>
            According to the authors, this generator is a full length generator, that is to say, its
            period is M = 2<superscript>31</superscript> = 214748364.
        </para>
        <para>
            The <literal>"normal"</literal> random number generator is based on
            the Box-Muller method, where source of the uniform random numbers is Urand.
        </para>
    </refsection>
    <refsection>
        <title>The statistical quality of the generator</title>
        <para>
            Better random number generators are available from
            the <link linkend="grand">grand</link> function, in the
            sense that they have both a larger period and better statistical properties.
            In the case where the quality of the random numbers matters, we should
            consider the <literal>grand</literal> function instead.
            Moreover, the <literal>grand</literal> function has more features.
        </para>
    </refsection>
    <refsection role="see also">
        <title>See also</title>
        <simplelist type="inline">
            <member>
                <link linkend="grand">grand</link>
            </member>
            <member>
                <link linkend="ssrand">ssrand</link>
            </member>
            <member>
                <link linkend="sprand">sprand</link>
            </member>
        </simplelist>
    </refsection>
</refentry>
