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

#if @HELP_COLRANDOMIZE

    COLRANDOMIZE

    Purpose: Randomize the column order of an array.

    Syntax:  COLRANDOMIZE(s, idx)

             (r, k) = COLRANDOMIZE(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 column reordered array.

             (r, k) = COLRANDOMIZE(s) returns the randomly column 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: colrandomize(w1)

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

             W2 contains the series {1, 2, 3, 4, 5}. For a single column,
             COLRANDOMIZE does not alter the input.

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

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

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

             The actual result in W2 may differ.

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

             The columns of W1 are randomly reordered in W2 and restored
             in W3.

    Remarks:
             COLRANDOMIZE randomly reorders the columns of a series or array.
             For a single column input, the original series is returned.

             See ROWRANDOMIZE to reorder the rows columns of an array.

             See RANDOMIZE to reorder the elements of an array.

    See Also:
             Randperm
             Randomize
             Rowrandomize

#endif


/* randomize columns */
colrandomize(s, idx = {})
{
        if ((argc < 1) || not(isarray(s)) || not(isarray(idx)))
        {
                error(sprintf("%s - input series required", __FUNC__))
        }

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

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