View Raw SPL
/*****************************************************************************
*                                                                            *
*   ROWRANDOMIZE.SPL Copyright (C) 2023 DSP Development Corporation          *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:          Randy Race                                              *
*                                                                            *
*   Synopsis:        Randomly reorder rows of an input array                 *
*                                                                            *
*   Revisions:        5 Apr 2023  RRR  Creation                              *
*                                                                            *
*****************************************************************************/

#if @HELP_ROWRANDOMIZE

    ROWRANDOMIZE

    Purpose: Randomize the row order of each column of an array.

    Syntax:  ROWRANDOMIZE(s, idx)

             (r, k) = ROWRANDOMIZE(s, idx)

                 s - A series or array, the input to randomize.

               idx - An optional series, the indices of a previous
                     randomize used to unscramble the input.


    Returns: A series or array, the randomly row reordered array.

             (r, k) = ROWRANDOMIZE(s) returns the randomly row reordered
             array and the indices used to perform the reordering. The
             returned indices can be used to restore the result to the
             original order.

    Example:
             W1: 1..5
             W2: rowrandomize(w1)

             W1 contains the series {1, 2, 3, 4, 5}.

             W2 contains the series {5, 4, 2, 1, 3}. The actual result may
             differ.

    Example:
             W1: 1..5
             W2: (r, k) = rowrandomize(w1);r
             W3: rowrandomize(w2, k)

             W1 contains the series {1, 2, 3, 4, 5}.

             W2 contains the series {5, 4, 2, 1, 3}. The actual result may
             differ.

             W3 contains the series {1, 2, 3, 4, 5}, the original series.

    Example:
             W1: ravel(1..12, 4)
             W2: (r, k) = rowrandomize(w1);r
             W3: rowrandomize(w2, k)

             W1 == {{1, 5,  9},
                    {2, 6, 10},
                    {3, 7, 11},
                    {4, 8, 12}}

             W2 == {{4, 7, 10},
                    {2, 5, 12},
                    {1, 6,  9},
                    {3, 8, 11}}

             The actual result in W2 may differ.

             W3 == {{1, 5,  9},
                    {2, 6, 10},
                    {3, 7, 11},
                    {4, 8, 12}}

             The rows of each column of W1 are independently randomly
             reordered in W2 and restored in W3.

    Remarks:
             ROWRANDOMIZE independently shuffles the row elements within each column
             of an array.

             For a single row input, the original series is returned.

             See ROWPERM to randomly permute the rows of an array.

             See COLRANDOMIZE to independently shuffle the column elements within
             each row of an array.

             See RANDOMIZE to reorder the elements of an array.

    See Also:
             Colperm
             Colrandomize
             Randperm
             Randomize
             Rowperm
#endif


/* randomize rows - each column randomized independently */
ITERATE rowrandomize(s, idx = {})
{
        if ((argc < 1) || not(isarray(s)) || not(isarray(idx)))
        {
                error(sprintf("%s - input series required", __FUNC__))
        }

        if (isempty(idx))
        {
                /* generate permuted row indices */
                idx = randperm(length(s));
        }
        else
        {
                /* unscramble given row indices */
                idx = grade(idx, 1);
        }

        if (outargc > 1)
        {
                return(s[idx], idx);
        }
        else
        {
                return(s[idx]);
        }
}