How to generate all pairs of two vectors in MATLAB using vectorized code?

More than once I had to generate all possible pairs of two vectors in MATLAB, which I do for loops that occupy several lines of code ie

vec1 = 1:4; vec2 = 1:3; i = 0; pairs = zeros([4*3 2]); for val1 = vec1 for val2 = vec2 i = i + 1; pairs(i,1) = val1; pairs(i,2) = val2; end end 

Creates ...

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

There must be a better way to do this, which is more MATLAB'esque?

nb nchoosek does not execute the inverse pairs that I need (i.e. 2 1 , as well as 1 2 ), I cannot just cancel and add the nchoosek output because the symmetric pairs will be included twice.

+45
matlab combinations
Sep 16 2018-11-11T00:
source share
8 answers

Try

 [p,q] = meshgrid(vec1, vec2); pairs = [p(:) q(:)]; 

See the MESHGRID documentation. Although this is not exactly what this function is intended for, but if you squinted that what you are asking for is exactly what it does.

+90
Sep 16 '11 at 15:37
source share

you can use

 a = 1:4; b = 1:3; result = combvec(a,b); result = result' 
+12
May 12 '14 at 14:35
source share

You can do this by replicating matrices using repmat , and then turning the result into a column vector using reshape .

 a = 1:4; b = 1:3; c = reshape( repmat(a, numel(b), 1), numel(a) * numel(b), 1 ); d = repmat(b(:), length(a), 1); e = [cd] e = 1 1 1 2 1 3 2 1 2 2 2 3 3 1 3 2 3 3 4 1 4 2 4 3 

Of course, you can get rid of all the intermediate variables from the above example.

+3
Sep 16 '11 at 15:37
source share

Another collection solution:

 [idx2, idx1] = find(true(numel(vec2),numel(vec1))); pairs = [reshape(vec1(idx1), [], 1), reshape(vec2(idx2), [], 1)]; 
+3
Apr 09 '13 at 16:42 on
source share

You can use simple old matrix operations, for example. at

 x = [3,2,1]; y = [11,22,33,44,55]; v = [(ones(length(y),1) * x)(:), (ones(length(x), 1) * y)'(:)] 

Edit: this is Octave syntax, MATLAB will look like this:

 x = [3,2,1]; y = [11,22,33,44,55]; A = ones(length(y),1) * x; B = (ones(length(x), 1) * y)'; v = [A(:) B(:)] 

in both cases the result will be

 v = 3 11 3 22 3 33 3 44 3 55 2 11 2 22 2 33 2 44 2 55 1 11 1 22 1 33 1 44 1 55 
+2
May 23 '17 at 20:59
source share

Here's more MATLAB'esque way to find combinations. It can also be easily expanded to more than 2 vectors (as well as non-numerical combinations):

 v1 = 1: 1: 3; v2 = 11: 11: 44; v3 = 111:111:555; dimensions = cellfun(@numel, {v1,v2,v3}); [i1,i2,i3] = ind2sub(dimensions, 1:prod(dimensions)); combinations = [v1(i1); v2(i2); v3(i3)]' 
+1
May 24 '16 at
source share

Starting with version R2015a, you can do this with repelem and repmat :

 >> vec1 = 1:4; >> vec2 = 1:3; >> pairs = [repelem(vec1(:), numel(vec2)) ... repmat(vec2(:), numel(vec1), 1)] pairs = 1 1 1 2 1 3 2 1 2 2 2 3 3 1 3 2 3 3 4 1 4 2 4 3 

This type of solution avoids the additional intermediate variables necessary for some other solutions (for example, based on meshgrid ), which can lead to memory problems for large vectors.

+1
Jun 24 '19 at 16:03
source share

What you are looking for is a Cartesian product.

cartprod is a function that implements it. You can find it in a linear algebra package, so you will need to do:

  >> pkg install -forge linear-algebra >> pkg load linear-algebra >> sortrows(cartprod(1:4,1:3)) ans = 1 1 1 2 1 3 2 1 2 2 2 3 3 1 3 2 3 3 4 1 4 2 4 3 
0
Apr 11 '16 at 19:32
source share



All Articles