4

There are two vectors:

a = 1:5;
b = 1:2;

in order to find all combinations of these two vectors, I am using the following piece of code:

[A,B] = meshgrid(a,b);
C = cat(2,A',B');
D = reshape(C,[],2);

the result includes all the combinations:

D =

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

now the questions:

1- I want to decrease the number of operations to improve the performance for vectors with bigger size. Is there any single function in MATLAB that is doing this?

2- In the case that the number of vectors is more than 2, the meshgrid function cannot be used and has to be replaced with for loops. What is a better solution?

NKN
  • 6,482
  • 6
  • 36
  • 55

2 Answers2

3

For greater than 2 dimensions, use ndgrid:

>> a = 1:2; b = 1:3; c = 1:2;
>> [A,B,C] = ndgrid(a,b,c);
>> D = [A(:) B(:) C(:)]
D =
     1     1     1
     2     1     1
     1     2     1
     2     2     1
     1     3     1
     2     3     1
     1     1     2
     2     1     2
     1     2     2
     2     2     2
     1     3     2
     2     3     2

Note that ndgrid expects (rows,cols,...) rather than (x,y).

This can be generalized to N dimensions (see here and here):

params = {a,b,c};
vecs = cell(numel(params),1);
[vecs{:}] = ndgrid(params{:});
D = reshape(cat(numel(vecs)+1,vecs{:}),[],numel(vecs));

Also, as described in Robert P.'s answer and here too, kron can also be useful for replicating values (indexes) in this way.

If you have the neural network toolbox, also have a look at combvec, as demonstrated here.

Community
  • 1
  • 1
chappjc
  • 30,359
  • 6
  • 75
  • 132
1

One way would be to combine repmat and the Kronecker tensor product like this:

[repmat(a,size(b)); kron(b,ones(size(a)))]'
ans =

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

This can be scaled to more dimensions this way:

a = 1:3;
b = 1:3;
c = 1:3;

x = [repmat(a,1,numel(b)*numel(c)); ...
     repmat(kron(b,ones(1,numel(a))),1,numel(c)); ...
     kron(c,ones(1,numel(a)*numel(b)))]'

There is a logic! First: simply repeat the first vector. Secondly: Use the tensor product with the dimension of the first vector and repeat it. Third: Use the tensor product with the dimension of (first x second) and repeat (in this case there is not fourth, so no repeat.

Stewie Griffin
  • 14,889
  • 11
  • 39
  • 70
  • 1
    These are good `kron` tricks. (p1) I gave your answer a nudge in mine, since it is a nice fast way for 2 or 3 dimensions that I like to use too. – chappjc Feb 26 '14 at 22:56