I want to generate a set of vectors with length N. Each of the element in the vector has K possibilities (choosing from integers 1 to K).
For example, if N=2 and K=2, the set of vectors are [0 0], [0 1], [1 0] and . [1 1]. Basically, the number of vectors I want to generate equals to K^N.
- 293
- 1
- 9
-
Is K the same for each entry? – Ian Riley Oct 08 '16 at 22:10
-
Yes, the first element is selected from 1 to K. So do the other elements. – MIMIGA Oct 08 '16 at 22:13
-
2What you want is a Cartesian product. You can use [this answer](http://stackoverflow.com/a/21895344/2586922) with input `vectors = repmat({0:K-1}, 1, N);` – Luis Mendo Oct 09 '16 at 01:18
3 Answers
I asked a similar question yesterday on the MATLAB chat; I'm not sure what the most efficient way is to adapt it to any general K.
One solution that works, but is inefficient because it keeps resizing out:
out = [1:K]'
for ii = 2:N
out = [ repmat(out,K,1) repelem([1:K]', K^(ii-1), 1)];
end
Here is a general solution for that (if you have MATLAB 2015a or newer):
N = 3;
elem = [6 9 4]; % you can change this to be any vector
K = numel(elem);
out = zeros(K^N,N);
for k = 1:N
out(:,k) = repmat(repelem(elem,K^(N-k)).',K^(k-1),1);
end
so for N = 2 and elem = 1:2 you get:
out =
1 1
1 2
2 1
2 2
where each row of out is one unique combination.
- 10,350
- 3
- 34
- 59
First way
This method is based on the fact that these vectors look like base K representations of a sequence of numbers:
N = 2;
K = 2;
out = zeros(K^N, N);
vec = (0:K^N-1).';
for k = N:-1:1
out(:,k) = mod(vec, K);
vec = floor(vec/K);
end
With this output:
out =
0 0
0 1
1 0
1 1
out(k,:) is your k'th vector. Note that if you instead prefer to have [1 1], [1 2], ..., you can simply add 1 to out:
out + 1 =
1 1
1 2
2 1
2 2
Second way:
Since repelem was added in R2015a, if you are on an older version of Matlab, you should use a replacement for it. One of the convenient solutions in terms of readability is kron function:
N = 2;
K = 2;
vec = (0:K-1).';
out = zeros(K^N, N);
for k = 1:N
out(:, k) = repmat(kron(vec, ones(K^(N-k), 1)), K^(k-1), 1);
end
With same out as above.
- 1,897
- 13
- 23