How to generate all pairs from two vectors in MATLAB using vectorised code?
More than once now I have needed to generate all possible pairs of two vectors in MATLAB which I do with for loops which take up a fair few lines of code i.e.
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
Generates ...
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?
n.b. nchoosek
does not do the reversed pairs which is what I need (i.e. 2 1
as well as 1 2
), I can't just reverse and append the nchoosek
output because the symmetric pairs will be included twice.
Try
[p,q] = meshgrid(vec1, vec2);
pairs = [p(:) q(:)];
See the MESHGRID documentation. Although this is not exactly what that function is for, but if you squint at it funny, what you are asking for is exactly what it does.
You may use
a = 1:4;
b = 1:3;
result = combvec(a,b);
result = result'
Another solution for collection:
[idx2, idx1] = find(true(numel(vec2),numel(vec1)));
pairs = [reshape(vec1(idx1), [], 1), reshape(vec2(idx2), [], 1)];
You could do it by replicating the 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 = [c d]
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 example above.
You can use plain old matrix operations, e.g. in
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, 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