Code covered by the BSD License  

Highlights from
NCHOOSE2 (v2.1 - jun 2008)

from NCHOOSE2 (v2.1 - jun 2008) by Jos (10584)
all combinations of two elements

nchoose2(X)
function Y = nchoose2(X)
% NCHOOSE2 - all combinations of two elements
%   Y = NCHOOSE2(X) returns all combinations of two elements of the array X.
%   It is the fast, vectorized version of NCHOOSEK(X,2).  X can be any type
%   of array.
%
%   Example:
%    nchoose2([10 20 30 40])
%     % -> 10    20
%     %    10    30
%     %    10    40
%     %    20    30
%     %    20    40
%     %    30    40
%
%    nchoose2({'a','b','c','d','e'})
%     % -> 'a'  'b'
%     %    'a'  'c'
%     %      ...
%     %    'c'  'e'
%     %    'd'  'e'
%
%   See also NCHOOSEK, PERMS
%            COMBN, NCHOOSE, ALLCOMB (on the File Exchange)

% for Matlab R13+
% version 2.1 (jun 2008)
% (c) Jos van der Geest
% email: jos@jasen.nl

% History
% 1.0, sep 2007 - created, for faster solution of nchoosek(x,2)
% 2.0, may 2008 - inspired to put on the FEX, by submission #20110 by S.
%                 Scaringi, and review by John D'Errico
%               - optimized engine, added extensive help and comments
% 2.1, jun 2008 - catch error when X has less than two elements
%                 (error pointed out by Urs Schwarz)

N = numel(X) ;
if N<2
    warning('nchoose2:InputTooSmall','Input has less than two elements') ;
    Y = [] ;    
elseif N==2,
    Y = X(:).' ; % output is a row vector
else 
% by creating an (N*(N-1)/2)-by-2 index matrix (where N is the number of
% elements of X), the output can be retrieved directly. This index matrix
% equals nchoosek(1:numel(X),2)
                                    % Example for N = 4 ->
    V  = N-1:-1:2 ;               %  V : 3 2
    ri = cumsum([1 V],2) ;          % ri : 1 4 6

% putting a row matrix into a column works because ind does not exist yet.
% it will also fill the first column with zeros.
    ind(ri,2) = [0 -V] + 1 ;        % ind -> c1: 0 0 0  0 0  0]
                                    %        c2: 1 0 0 -2 0 -1]
    ind(ri,1) = 1 ;                 % ind -> c1: 1 0 0  1 0  1]
                                    %        c2: 1 0 0 -2 0 -1]
    ind(:,2) = ind(:,2) + 1 ;       % ind -> c1: 1 0 0  1 0  1]
                                    %        c2: 2 1 1 -1 1  0]
    ind = cumsum(ind,1) ;           % ind -> c1: 1 1 1 2 2 3]
                                    %        c2: 2 3 4 3 4 4]
    Y = X(ind) ;                    % index into X
end

%   Notes:
%   - NCHOOSE2(X) is much faster than NCHOOSEK(X,2). It is also faster than
%     another solution ("nCtwo", FEX # 20110, May 28th 2008, Simone
%     Scaringi), especially for smaller arrays. It is also more memory
%     efficient than a solution based on a suggestion by John D'Errico in
%     his review of FEX #20110:
%        [I,J] = find(tril(ones(numel(x)),-1));
%        y = x([J(:) I(:)]);
%     The latter solution is a little faster for shorter vectors, but
%     slower and memory consuming for larger vectors. Moreover, it may
%     require a call to  sortrows to get the same order as nchoosek.
%   - specifying the dimension for cumsum is slightly faster

Contact us at files@mathworks.com