File Exchange

image thumbnail

VChooseKO

version 1.0 (15.4 KB) by

Choose K elements from a vector without repetitions and with order [MEX]

4 Downloads

Updated

View License

VChooseKO(V, K) creates a matrix, which rows are all permutations of choosing K elements of the vector V with order and without repetitions.

INPUT:
  V: Array of class DOUBLE, SINGLE, (U)INT8/16/32/64, LOGICAL, CHAR.
  K: Number of elements to choose.

OUTPUT:
  Y: [N!/(N-K)!, K] matrix with N is the number of elements of V.
     Y has the same class as the input V.
     The rows are sorted in lexicographical order: smaller indices at first.

EXAMPLES:
  Choose 2 elements from [1, 2, 3]:
    VChooseKO(1:3, 2) % ==> [1,2; 1,3; 2,1; 2,3; 3,1; 3,2]
  For speed cast the input to integer types or SINGLE whenever possible:
    Y = VChooseKO(uint8(1:100), 3); % 5 times faster than:
    Y = VChooseKO(1:100, 3);
  To get the permutations of cell arrays, permute the index:
    C = {'a', 'b', 'c', 'd'};
    C2 = C(VChooseKO(uint8(1:4), 2))
    ==> C2 = {'a','b'; 'a','c'; 'a','d'; 'b','a'; 'b','c'; 'b','d'; ...
              'c','a'; 'c','b'; 'c','d'; 'd','a'; 'd','b'; 'd','c'}
  Equivalent to PERMS:
    isequal(sortrows(perms(1:5)), VChooseKO(1:5, 5)) % TRUE
  For an output with sorted values (not indices!), sort the input:
    X = [3, 1, 2]; VChooseKO(sort(X), 3)
    ==> [1,2,3; 1,3,2; 2,1,3; 2,3,1; 3,1,2; 3,2,1]

The output of VCHOOSEKO(V, K) is equivalent to COMBINATOR(NUMEL(V), K, 'p'), but is remarkably faster (see screenshot). The lexicographical output of VCHOOSEKO can be a benefit also, because a time-consuming SORTROWS can be omitted.

Tested: Matlab 6.5, 7.7, 7.8, WinXP, 32 bit, Compilers: BCC5.5, LCC2.4/3.8, Open Watcom 1.8
The unit-test function TestVChooseKO is included to test the validitiy and compare the speed with PICK, COMBINATOR and Matlab's PERMS.

Precompiled mex: http://www.n-simon.de/mex
See also:
  VChooseK (no repetitions, no order): FEX #26190
  VChooseKRO (repetitions, order): FEX #26242
  VChooseKR (repetitions, no order): FEX #26277

I'd appreciate suggestions for improvements and bug reports sent through email - thanks.

Comments and Ratings (2)

Peter Li

Peter Li (view profile)

This sounds useful, but would be nice to be able to generate the permutations in blocks so that if there are too many for memory it can still be done in batches.

I think I will make a version based on C++ STL NEXT_PERMUTATION.

Jan Simon

Jan Simon (view profile)

This fails under 64-bit systems and -largeArrayDims. A bugfix is created soon.

MATLAB Release
MATLAB 7.8 (R2009a)

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video