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 ROWRANDOMIZE to reorder the rows of an array.

             See COLRANDOMIZE to reorder the columns of an array.

    See Also:
             Colrandomize
             Randomize
             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);
}