Here is my method that made me giggle with delight using nchoosek , although it is no better than @Luis Mendo made the decision.
In the above example, after 1000 starts, this solution took my car an average of 0.00065935 s compared to the decision made 0.00012877 s. For larger vectors following @Luis Mendo benchmarking, this solution is consistently slower than the accepted answer. However, I decided to publish it in the hope that maybe you will find something useful:
The code:
tic; v = {[1 2], [3 6 9], [10 20]}; L = [0 cumsum(cellfun(@length,v))]; V = cell2mat(v); J = nchoosek(1:L(end),length(v)); J(any(J>repmat(L(2:end),[size(J,1) 1]),2) | ... any(J<=repmat(L(1:end-1),[size(J,1) 1]),2),:) = []; V(J) toc
gives
ans = 1 3 10 1 3 20 1 6 10 1 6 20 1 9 10 1 9 20 2 3 10 2 3 20 2 6 10 2 6 20 2 9 10 2 9 20 Elapsed time is 0.018434 seconds.
Explanation:
L gets the length of each vector using cellfun . Although cellfun is basically a loop, it is effective here, given that your number of vectors should be relatively low to make this problem even practical.
V combines all vectors for easy access later (this assumes that you have entered all your vectors as strings. V 'will work for column vectors.)
nchoosek gets all the ways to select elements n=length(v) from the total number of elements L(end) . There will be more combinations than what we need.
J = 1 2 3 1 2 4 1 2 5 1 2 6 1 2 7 1 3 4 1 3 5 1 3 6 1 3 7 1 4 5 1 4 6 1 4 7 1 5 6 1 5 7 1 6 7 2 3 4 2 3 5 2 3 6 2 3 7 2 4 5 2 4 6 2 4 7 2 5 6 2 5 7 2 6 7 3 4 5 3 4 6 3 4 7 3 5 6 3 5 7 3 6 7 4 5 6 4 5 7 4 6 7 5 6 7
Since there are only two elements in v(1) , we need to throw out any lines where J(:,1)>2 . Similarly, where J(:,2)<3 , J(:,2)>5 , etc. Using L and repmat , we can determine if each element of J in the corresponding range, and then use any to remove lines that are any bad element.
Finally, these are not the actual values ββfrom V , but only the indices. V(J) will return the desired matrix.