2
votes

I have a question that is related to this post: "Cloning" row or column vectors. I tried to work around the answers posted there, yet failed to apply them to my problem.


In my case, I'd like to "clone" each row row of a matrix by converting a matrix like

A = [1,2; 3, 4; 5, 6]

into the matrix

B = [1, 2
     1, 2
     3, 4
     3, 4
     5, 6
     5, 6]

by repeating each row of A a number of times.


So far, I was able to work with repmat for a single row like

A = [1, 2];
B = repmat(A, 2, 1)

>> B = [1, 2
        1, 2]

I was trying to build a loop using that formula, in order to obtain the matrix wanted. The loop looked like

T = 3; N = 2;
for t = 1:T
    for I = 1:N
      B = repmat(C, 21, 1)
    end
end

Has anyone an idea how to correctly write the loop, or a better way to do this?

1
B = repmat(A,2,1) does not give the result you wrote. If I understand right your question, you want something like B=kron(A,[1;1])?Adiel

1 Answers

6
votes

kron

There are a few ways you can do this. The shortest way would be to use the kron function as suggested by Adiel in the comments.

A = [1,2; 3, 4; 5, 6];
B = kron(A, [1;1]);

Note that the number of elements in the ones vector controls how many times each row is duplicated. For n times, use kron(A, ones(n,1)).

kron calculates the kronecker tensor product, which is not necessarily a fast process, nor is it intuitive to understand, but it does give the right result!


reshape and repmat

A more understandable process might involve a combination of reshape and repmat. The aim is to reshape the matrix into a row vector, repeat it the desired number of times, then reshape it again to regain the two-column matrix.

B = reshape(repmat(reshape(A, 1, []), 2, 1), [], 2);

Note that the 2 within the repmat function controls how many times each row is duplicated. For n times, use reshape(repmat(reshape(A, 1, []), n, 1), [], 2).


Speed

A quick benchmark can be written:

% Setup, using a large A
A = rand(1e5, 2);
f = @() kron(A, [1;1]);
g = @() reshape(repmat(reshape(A, 1, []), 2, 1), [], 2);
% timing
timeit(f);
timeit(g);

Output:

  • kron option:
    0.0016622 secs
  • repmat/reshape option:
    0.0012831 secs

Extended benchmark over different sizes:

benchmark

Summary:

  • the reshape option is quicker (~25%) for just duplicating the rows once each, so you should go for this option if you want to end up with 2 of each row for a large matrix.

  • the reshape option appears to have complexity O(n) for the number of row repetitions. kron has some initial overhead, but is much quicker when you want many repetitions and hardly slows down because of them! Go for the kron method if you are doing more than a few repetitions.