2

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.

MIMIGA
  • 293
  • 1
  • 9

3 Answers3

0

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
Community
  • 1
  • 1
Ian Riley
  • 523
  • 2
  • 8
0

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.

EBH
  • 10,350
  • 3
  • 34
  • 59
0

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.

Erfan
  • 1,897
  • 13
  • 23