Code covered by the BSD License

### Highlights from nCtwo

Be the first to rate this file! 11 Downloads (last 30 days) File Size: 1.54 KB File ID: #20110 Version: 1.0

# nCtwo

### Simone Scaringi (view profile)

28 May 2008 (Updated )

All combinations of N elements taken two at the time.

File Information
Description

Usage - vec=nCtwo(dat) where dat is a vector of length N, produces a matrix with N*(N-1)/2 rows and 2 columns. Each row of the result vec has two of the elements in the vector dat. Similar to the MATLAB function NCHOOSEK(dat,2) but much faster.

Acknowledgements

This file inspired Nchoose2 (V2.1 Jun 2008) and V Choose K.

MATLAB release MATLAB 7 (R14)
Tags for This File   Please login to tag files.
 Please login to add a comment or rating.
Comments and Ratings (4)
01 Jun 2008 John D'Errico

Interestingly, I can do better than the triu code, still in an entirely vectorized solution. The code below has no additional memory allocation. But it is no faster than the other versions. According to profile, most of the time consumed is mainly in the very last line, just the simple lookup.

function IJ = nc2(nvec)
nvec = nvec(:);
n = length(nvec);
IJ = ones(n*(n-1)/2,1)*[0 1];
ind = cumsum([1;((n-1):-1:2)']);
IJ(ind,1) = 1;
IJ(1,2) = 2;
IJ(ind(2:end),2) = 2+((1-n):1:-2)';
IJ = nvec(cumsum(IJ,1));

Comment only
01 Jun 2008 Jos x@y.z

As for the present submission, it is pretty good and indeed fast. It contains help (including a H1 line). It unfortunately lacks internal comments and examples, and can be improved in this respect.

The following version of JD's excellent engine directly returns the rightly order output, and is a little less memory consuming (2*N-1 elements less...) :
[c2,c1] = find(tril(ones(numel(x)-1)));
y = x([c1(:) c2(:)+1]);

I have just submitted my own fast, vectorized alternative of nchoosek(x,2) to the FEX, which is also not memory consuming.

Comment only
30 May 2008 Simone Scaringi

Very clever and elegant solution John!

However when dealing with large N the step

[I,J] = find(triu(ones(length(nvec)),1));

requires lot's of ram, and nCtwo.m performs faster (even for small N)...

I know for loops are not appropriate within matlab, however one has to include some when dealing with big datasets...

Thanks...
Simo

Comment only
29 May 2008 John D'Errico

Cleaner is just this simple solution.

[I,J] = find(triu(ones(length(nvec)),1));
IJ = [I(:),J(:)];
IJ = nvec(IJ);

Comment only

Contact us