View Raw SPL
/*****************************************************************************
*                                                                            *
*   RANDN.SPL      Copyright (C) 2000-2015 DSP Development Corporation       *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:       Randy Race                                                 *
*                                                                            *
*   Synopsis:     Generates a normally distributed random array              *
*                                                                            *
*   Revisions:     7 Feb 2000  RRR  Creation                                 *
*                 14 Feb 2006  RRR  use builtin gnormarray for speed         *
*                 27 Aug 2015  RRR  unscale flag                             *
*                                                                            *
*****************************************************************************/


#if @HELP_RANDN

    RANDN

    Purpose: Generates a normally distributed random array

    Syntax:  RANDN(numrows, numcols, mean, std, unscale)

               numrows - An integer, number of output rows

               numcols - An optional integer, number of output columns,
                         defaults to numrows

                   mean - An optional real, mean of the distribution, defaults
                          to 0.0


                    std - An optional real, standard deviation of the
                          distribution, defaults to 1.0

                unscale - Optional.  An integer, the mean and standard
                          deviation scaling flag.
                            
                            0: Standard mode, scale the result to have the
                               specified mean and standard deviation
                               (default).

                            1: Raw mode, do not scale the result. The
                               result will have approximately the
                               specified mean and standard deviation.

             RANDN with no input arguments returns a scalar

    Returns: A scalar, series or array

    Example:
             randn(20, 5)

             Generates a 20 row by 5 column array of normally distributed
             random numbers with values between 0.0 and 1.0. Each column
             has a mean of 0 and a standard deviation of 1.

    Example:
             randn(20, 5, 10, 3)

             Same as above except each column has a mean of 10.0 and a
             standard deviation of 3.0.

    Example: 
             randn(20, 5, 10, 3, 1)

             Generates a 20 row by 5 column array of normally distributed
             random numbers from a population where the mean is 10.0 and
             the standard deviation is 3.0. Each column has a mean of
             approximately 10.0 and a standard deviation of approximately
             3.0.

    Example:
             randn

             Returns a single random real value chosen from a set of
             normally distributed random values with a mean of 0 and
             a standard deviation of 1.0.

    Remarks:
             RANDN uses GNORM to generate the random values. The SEEDRAND
             function determines the initial seed of the random number
             generator.

    See Also:
             Gnormal
             Grand
             Rand
             Seedrand

#endif


/* generate matrix of normally distributed random values */
SERIES randn(n, m, mean, std, unscale)
{
        local a, b, r, nr, nc;

        if (argc < 5)
        {
                if (argc < 4)
                {
                        if (argc < 3)
                        {
                                if (argc < 2)
                                {
                                        if (argc < 1)
                                        {
                                                /* pick value from series of 12 */
                                                a = gnorm(12, 1);
                                                b = castint(grand(1, 1, 1, 12));
                                                return(a[b]);
                                        }
                                
                                        m = n;
                                }
                        
                                mean = 0.0;
                        }
                
                        std = 1.0;
                }

                unscale = getconfig("randn_mode");
        }

        if (isarray(n))
        {
                /* series argument - get size */
                (nr, nc) = size(n);
                
                if (nr == 2 && nc == 1)
                {
                        /*
                         *  assume series came from size function,
                         *  e.g. randn(size(n))
                         */
                        
                        m = int(n[2]);
                        n = int(n[1]);
                }
                else
                {
                        /* e.g. randn(x) - obsolete */
                        n = nr;
                        m = nc;
                }
        }
        else
        {
                m = castint(m);
                n = castint(n);
        }

        if (m <= 0 || n <= 0)
        {
                /* empty series */
                return({});
        }

        if (m == 1)
        {
                /* no need for array */
                r = gnorm(n, 1, mean, std, unscale);
        }
        else
        {
                r = gnormarray(n, m, mean, std, unscale);
        }

        return(r);
}