View Raw SPL
/*****************************************************************************
*                                                                            *
*   RANDPERM.SPL Copyright (C) 2023 DSP Development Corporation              *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Randomly permute integers 1..n                              *
*                                                                            *
*   Revisions:    5 Apr 2023  RRR  Creation                                  *
*                                                                            *
*****************************************************************************/

#if @HELP_RANDPERM

    RANDPERM

    Purpose: Randomly permutes the sequence of integers from 1 to n.

    Syntax:  RANDPERM(n, k)

              n - The number of values to permute.

              k - An optional integer, the number of values to select
                  from the permutation. Must be <= n.


    Returns: A series, the permuted sequence.


    Example:
             W1: randperm(5)

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

    Example:
             W1: randperm(5, 3)

             W1 contains the series {4, 1, 2}. The actual result may
             differ.

    Remarks:
             RANDPERM(n) randomly permutes the sequence 1..n.

             RANDPERM(n, k) randomly permutes the sequence 1..n and returns
             k values from the permutation.

             The inputs N and K must be non-negative integers.

             RANDPERM returns an empty series for N == 0 or K == 0.

             See RANDOMIZE to reorder the elements of an array.

             See ROWPERM to permute the row of an array.

             See COLPERM to permute the columns of an array.

             See ROWRANDOMIZE to independently reorder the rows of
             an array.

             See COLRANDOMIZE to independently reorder the columns of
             an array.

    See Also:
             Colperm
             Colrandomize
             Randomize
             Rowperm
             Rowrandomize

#endif


/* randomly permute integer sequence 1..n */
randperm(n = 0, k = n)
{
        local r = {};

        if (not(isinteger(n)) || not(isinteger(k)) || n < 0 || k < 0)
        {
                error(sprintf("%s - non-negative integer required", __FUNC__));
        }

        if (n > 0)
        {
                /* create randomized indices */
                r = grade(grand(n, 1), 1);
        }

        if (k < n)
        {
                r = extract(r, 1, k);
        }
        else if (k > n)
        {
                error(sprintf("%s - input k must be <= %d", __FUNC__, n));
        }

        return(r);
}