Code covered by the BSD License  

Highlights from
VChooseK

Be the first to rate this file! 15 Downloads (last 30 days) File Size: 13.75 KB File ID: #26190
image thumbnail

VChooseK

by Jan Simon

 

23 Dec 2009

Choose K elements from a vector - MEX: 100 times faster than NCHOOSEK

| Watch this File

File Information
Description

VChooseK(V, K) creates a matrix, which rows are all combinations of choosing K elements of the vector V without order and without repititions.

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

OUTPUT:
  Y: Matrix of size [N!/K!(N-K)!, K] with N is the number of elements of V.
    Y has the same class as the input V.

The output equals Matlab's NCHOOSEK, except that NCHOOSEK replies the number of combinations for a scalar V:
   VChooseK(-1, 1) replies [-1]: One element taken out of a set of length one.
   NCHOOSEK(-1, 1) fails at calculating N!/K!(N-K)!.

EXAMPLES:
  Choose 2 elements from [1,2,3,4]:
    VChooseK(1:4, 2)
    ==> [1,2; 1,3; 1,4; 2,3; 2,4; 3,4]
  For speed cast the input to integer types if possible:
    Y = double(VChooseK(int16(1:1000), 2);
  is faster than:
    Y = VChooseK(1:1000, 2);
  To get the combinations of cell arrays, use the combinations of the index:
    C = {'a', 'b', 'c', 'd'};
    C2 = C(VChooseK(1:4, 2))
    ==> C2 = {'a', 'b'; 'a', 'c'; 'a', 'd'; 'b', 'c'; 'b', 'd'; 'c', 'd'}

INSPIRATION:
Jos van der Geest has published an efficient NCHOOSE2, which is much faster than Matlab's NCHOOSEK: http://www.mathworks.com/matlabcentral/fileexchange/20144
I was curious, if a MEX version is much faster. At first I've created NChoose2q, which was 5 times faster than Jos' Matlab implementation. But the algorithm was so simple in C and did not consume temporary memory, that I've expanded it to K=3,4,5 soon. The algorithm for free K was more challenging, but it needs just 3*K pointers for temporary memory. Therefore it is much faster than Matlab's NCHOOSEK (Matlab 7.8, 1.5GHz Pentium-M, 512 MB):
  NCHOOSEK(1:50, 5): 45.30 sec
  VChooseK(1:50, 5): 0.32 sec => 141 times faster
  NCHOOSEK(1:20, 16): 0.52 sec
  VChooseK(1:20, 16) 0.0024 sec => 216 times faster
  NCHOOSEK(int8(1:40), 4): 0.64 sec
  VChooseK(int8(1:40), 4): 0.001562 sec => 410 times faster

The powerful COMBINATOR of Matt Fig handles repititions and ordered sequences also, but for its specific job VChooseK is remarkably faster (see screen shot).

Tested: Matlab 6.5, 7.7, 7.8, WinXP
Compilers: BCC5.5, LCC2.4/3.8, Open Watcom 1.8
Please run the unit-test TestVChooseK after compiling and for speed comparisons.

Acknowledgements

The author wishes to acknowledge the following in the creation of this submission:
Picking elements from a set, nCtwo, NCHOOSE2 (v2.1 - jun 2008), combinations , COMBINATOR -combinations AND permutations
This submission has inspired the following:
VChooseKO, nsumk, ICHOOSE

MATLAB release MATLAB 7.8 (R2009a)
Other requirements This replaces my former FEX submission NChoose2q.
Tags for This File  
Everyone's Tags
Tags I've Applied
Add New Tags Please login to tag files.
Comments and Ratings (4)
01 Jan 2010 Jan Simon

I've deleted the file NChoose2q (limited to K==2), because it had no advantages compared with the more general VChooseK. Please mail me, if this causes problems for anybody.

22 Jan 2010 Jan Simon

For choosing with/without Repitions and Order see also my submissions:
O: http://www.mathworks.com/matlabcentral/fileexchange/26397
R: http://www.mathworks.com/matlabcentral/fileexchange/26277
RO: http://www.mathworks.com/matlabcentral/fileexchange/26242

19 Dec 2011 Mark Whirdy

Hi Jan

I went to use this but came across a snag at the first hurdle, have you an idea of where the problem may lie?

==== Test VChooseK: 19-Dec-2011 18:15:35
Version: J:\Financial_Engineering\QUANT FIXED INCOME\...\VChooseK.m

== DOUBLE, K = 1:
Error in ==> VChooseK at 1
function Y = VChooseK(X, K)

??? Output argument "Y" (and maybe others) not assigned during call to "J:\Financial_Engineering\...\VChooseK.m>VChooseK".

Error in ==> TestVChooseK at 66
      S = VChooseK(my_cast([], aClass), K);

19 Dec 2011 Jan Simon

Dear Mark, before you can use the function, you have to compile it as explained in the documentation:
  mex -O VChooseK.c
An explicite message will appear in a future version.

Please login to add a comment or rating.
Tag Activity for this File
Tag Applied By Date/Time
nchoosek Jan Simon 24 Dec 2009 10:02:55
choose Jan Simon 24 Dec 2009 10:02:55
pick Jan Simon 24 Dec 2009 10:02:55
statistics Jan Simon 24 Dec 2009 10:02:55
select Jan Simon 24 Dec 2009 10:02:55
permutations Jan Simon 29 Dec 2009 17:23:20
combinations Jan Simon 29 Dec 2009 17:23:28

Contact us at files@mathworks.com