Asked by Luca Freilino
on 13 Apr 2019

Hi everyone. I have a code (attached at the end) that works. It has as input 6 variables: numbers is a vector, in this case [1 2 2 1], number_surrogates is a vector, value_n and value_a are vectors (of different length), while value_i and value_c are matrices. The problem is that I have to find the final matrix "combinations", which elements are all the possible combinations of the input elements. (eg given comb_n = [1:12], comb_i = [13 14; 13 15; 13 16; ... ; 16 19; 16 20; ....; 28 29], comb_c = [30 31; 30, 32; ...; 35 38; ....; 38 39] and comb_a = [40:47]. the output should be [1 13 14 30 31 40; 1 13 14 30 31 41; ..... ; 3 16 24 36 39 45; ..... ; 12 28 29 38 39 47]. (I wish I had been as much clear as possible). Now, my question is: is there an alternative way to the for cycle? I'm looking for something much faster and computationally better, since loop cycle "kills" the code. Thank you in advance, Luca.

function [comb_n,comb_i,comb_c,comb_a,combinations] = MyFunctionCombinations(numbers,number_surrogates,value_n,value_i,value_c,value_a)

comb_n = nchoosek(value_n,numbers(1));

comb_i = nchoosek(value_i,numbers(2));

comb_c = nchoosek(value_c,numbers(3));

comb_a = nchoosek(value_a,numbers(4));

index = 1;

combinations = zeros((length(comb_n)*length(comb_i)*length(comb_c)*length(comb_a)),number_surrogates,'single');

N = 1:length(comb_n);

I = 1:length(comb_i);

C = 1:length(comb_c);

A = 1:length(comb_a);

for n = N

for i = I

for c = C

for a = A

combinations(index,1:number_surrogates) = [comb_n(n,:), comb_i(i,:), comb_c(c,:), comb_a(a,:)];

index = index+1;

end

end

end

end

end

Answer by Jan
on 13 Apr 2019

This is faster:

function [cn, ci, cc, ca, comb] = MyComb4(n, vn, vi, vc, va)

% Get combinations:

cn = nchoosek(single(vn), n(1));

ci = nchoosek(single(vi), n(2));

cc = nchoosek(single(vc), n(3));

ca = nchoosek(single(va), n(4));

% Number of combinations:

scn1 = size(cn, 1);

sci1 = size(ci, 1);

scc1 = size(cc, 1);

sca1 = size(ca, 1);

nCum = cumsum(n);

comb = zeros(nCum(end), scn1 * sci1 * scc1 * sca1, 'single');

index = 0;

v = zeros(nCum(4), 1, 'single');

for in = 1:scn1

v(1:nCum(1)) = cn(in,:);

for ii = 1:sci1

v(nCum(1)+1:nCum(2)) = ci(ii,:);

for ic = 1:scc1

v(nCum(2)+1:nCum(3)) = cc(ic,:);

for ia = 1:sca1

v(nCum(3)+1:nCum(4)) = ca(ia,:);

index = index + 1;

comb(:, index) = v;

end

end

end

end

comb = comb.';

end

The 2nd input is omitted. The output is created column-wise and transposed at the end, which is more efficient.

For the given inouts

[1,2,2,1], 6, 1:12, 13:29, 30:39, 40:47

This takes 0.52 instead of 1.90 sec on my i7, Matlab 2018b.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 4 Comments

## Jan (view profile)

## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/456142-combinations-of-vectors-and-matrices#comment_693615

## Luca Freilino (view profile)

## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/456142-combinations-of-vectors-and-matrices#comment_693620

## Luca Freilino (view profile)

## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/456142-combinations-of-vectors-and-matrices#comment_693625

## Jan (view profile)

## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/456142-combinations-of-vectors-and-matrices#comment_693627

Sign in to comment.