views:

106

answers:

4

Hi.

I am wondering whether there is an efficient way in MATLAB to generate all vectors of a fixed length with elements from a finite set.

For instance, how can I build all vectors of length 5 with only 0 or 1 as elements?

+3  A: 

not quite what you need, but permv generates vector permutations. If you do not find exact solution, you can adapt vector permutations.

permv

aaa
Thanks! I think this is exactly what i need.
Kiran Mudassir
@Kiran: Keep in mind that you have to first choose a 5-element vector of ones and zeroes to start with, then PERMS will give you every permutation of that.
gnovice
Thanks for the tip, gnovice. This makes my code much quicker then earlier and that is really good.
Kiran Mudassir
+1  A: 

New answer:

You can speed up the DEC2BIN solution suggested by AB (with an assist by woodchips) by instead using the BITGET function. There are two ways to approach this. The first uses the REPMAT function to make the inputs equal in size (both 32-by-5 matrices):

allCombos = bitget(repmat((0:31)',1,5),repmat(5:-1:1,32,1));

And the second simply calls BITGET once for every individual bit you want to get:

vec = (0:31)';
allCombos = [bitget(vec,5) bitget(vec,4) bitget(vec,3) ...
             bitget(vec,2) bitget(vec,1)];

And here are some sample timings:

     Method      |  Average Time
-----------------+------------------
  DEC2BIN        |   0.000788 s
  BITGET+REPMAT  |   0.000727 s
  BITGET x5      |   0.000045 s

As you can see, the unrolled BITGET is very fast.


Old answer: (for posterity)

If you are wanting to build a matrix of every possible vector of zeroes and ones that has a length of 5, this would be one way to do it using the functions PERMS and UNIQUE (since PERMS creates repeated rows):

allCombos = [0 0 0 0 0;
             unique(perms([0 0 0 0 1]),'rows'); ...
             unique(perms([0 0 0 1 1]),'rows'); ...
             unique(perms([0 0 1 1 1]),'rows'); ...
             unique(perms([0 1 1 1 1]),'rows'); ...
             1 1 1 1 1];
gnovice
+7  A: 

The proper way to build all vectors of length 5 with only 0 or 1 as elements is

a = dec2bin(0:31,5) - '0';

I hope you see why.

AVB
+1 Nice answer. The only possible drawback is that DEC2BIN can be *painfully* slow.
gnovice
@gnovice: You've made me go and look at DEC2BIN source. Yes, it's probably not very efficient - but it's such a cute one-liner! Thanks.
AVB
Rather than looping, get used to not looping.>> tic,a=zeros(10,1024);for x=0:1023,a(:,x+1)=str2num(dec2bin(x,10)');end,tocElapsed time is 0.105492 seconds.>> tic,a = dec2bin(0:1023) - '0';tocElapsed time is 0.000868 seconds.
woodchips
@woodchips: Well, the `-'0'` is a cool trick I didn't know about, so I couldn't vectorize that loop (I tried, of course). Thanks! I'll edit my answer - this makes it a one-liner.
AVB
+3  A: 

MathWorks' FileExchange is your friend:

So using the first function, its as easy as:

VChooseKRO([0 1], 5)

You can even make it work for a cell array of strings as the finite set:

C = {'a' 'b' 'c' 'd'};
C( VChooseKRO(1:numel(C), 2) )
merv

related questions