4

Suppose I have a matrix defined as follows

M = [C1 C2 C3 C4]

Where the C's are column vectors I want some efficient (i.e. no for loops) way of producing A vector such that

ResultVec = [C1 C2; 
             C1 C3; 
             C1 C4;
             C2 C3; 
             C2 C4; 
             C3 C4]

Thanks in advance!

Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
David
  • 326
  • 1
  • 11

2 Answers2

10

That is, what nchoosek does:

M = [ 1 2 3 4 ];

R = nchoosek(M,2);

returns:

R =

     1     2
     1     3
     1     4
     2     3
     2     4
     3     4

I don't know if it's your intention but nchoosek is Matlabs implementation of The number of k-combinations from a given set S of n elements without repetition (Wikipedia)

The function nchoosek is performance wise not very efficient though. But there are equivalents on File Exchange, which are much(!!) faster and doing the same.


Just to make it clear, it's not just working for the fairly simple example above, and is not returning any indices. It directly transforms the matrix as desired.

M = [ 21 42 123 17 ];

returns:

R =

    21    42
    21   123
    21    17
    42   123
    42    17
   123    17
Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
  • Good to know about this use of `nchoosek`! I stole it for an update of my answer... – A. Donda Dec 06 '13 at 15:23
  • @A.Donda I don't get what you need the other lines for? `nchoosek` is absolutely everything you need. – Robert Seifert Dec 06 '13 at 15:32
  • The question was about arranging the columns of a matrix `M`. What you provided are just the indices used to do so. What you get is `R = [1 2; ...`, what he wants is `R = [C1, C2; ...`, where `C1 = M(:, 1)` etc. – A. Donda Dec 06 '13 at 15:33
  • 1
    @A.Donda that's not true. If `M = [ 21 42 123 17 ];` it works also. – Robert Seifert Dec 06 '13 at 15:34
  • True, I didn't notice. It does not, however, work for `M = [ 21 42 123 17 ; 1 2 3 4 ];`. – A. Donda Dec 06 '13 at 15:36
  • I didn't mean to offend you by adopting your `nchoosek`. If you'd like, I can remove it from my answer. But still, my answer works for the general case that the poster asked for, and yours doesn't. Moreover, your answer didn't really explain that `nchoosek` does more than produce indices. – A. Donda Dec 06 '13 at 15:41
  • 1
    @A.Donda Don't worry I'm not offended at all, I just don't see the necessity of your further steps ;) I'll improve my answer a bit. `nchoosek` has nothing to do with indices, it is just matlabs implementation for [combinations](http://en.wikipedia.org/wiki/Combination) – Robert Seifert Dec 06 '13 at 15:54
4

This is the simplest way I've come up with:

n = size(M, 2);
[j, i] = ind2sub([n n], find(~triu(ones(n))));
ResultVec = M(:, [i j]);
ResultVec = reshape(ResultVec, [], 2)
A. Donda
  • 8,381
  • 2
  • 20
  • 49