I would like to generate all the possible combinations of the elements of a given number of vectors.
For example, for [1 2]
, [1 2]
and
Consider this solution using the NDGRID function:
sets = {[1 2], [1 2], [4 5]};
[x y z] = ndgrid(sets{:});
cartProd = [x(:) y(:) z(:)];
cartProd =
1 1 4
2 1 4
1 2 4
2 2 4
1 1 5
2 1 5
1 2 5
2 2 5
Or if you want a general solution for any number of sets (without having to create the variables manually), use this function definition:
function result = cartesianProduct(sets)
c = cell(1, numel(sets));
[c{:}] = ndgrid( sets{:} );
result = cell2mat( cellfun(@(v)v(:), c, 'UniformOutput',false) );
end
Note that if you prefer, you can sort the results:
cartProd = sortrows(cartProd, 1:numel(sets));
Also, the code above does not check if the sets have no duplicate values (ex: {[1 1] [1 2] [4 5]}
). Add this one line if you want to:
sets = cellfun(@unique, sets, 'UniformOutput',false);
This late answers provides two additional solutions, where the second is the solution (in my opinion) and an improvement on Amro's answer solution with ndgrid
by applying MATLAB's powerful comma-separated lists instead of cell arrays for high performance,
Just as Amro did in his answer, the comma-separated lists syntax (v{:}
) supplies both the inputs and outputs of ndgrid
. The difference (fourth line) is that it avoids cellfun
and cell2mat
by applying comma-separated lists, again, now as the inputs to cat
:
N = numel(a);
v = cell(N,1);
[v{:}] = ndgrid(a{:});
res = reshape(cat(N+1,v{:}),[],N);
The use of cat
and reshape
cuts execution time almost in half. This approach was demonstrated in my answer to an different question, and more formally by Luis Mendo.
we can also use the 'combvec' instruction in matlab
no_inp=3 % number of inputs we want...in this case we have 3 inputs
a=[1 2 3]
b=[1 2 3]
c=[1 2 3]
pre_final=combvec(c,b,a)';
final=zeros(size(pre_final));
for i=1:no_inp
final(:,i)=pre_final(:,no_inp-i+1);
end
final
Hope it helps. Good luck.
Try ALLCOMB function at FileExchange.
If you store you vectors in a cell array, you can run it like this:
a = {[1 2], [1 2], [4 5]};
allcomb(a{:})
ans =
1 1 4
1 1 5
1 2 4
1 2 5
2 1 4
2 1 5
2 2 4
2 2 5