0

Could you help me to write down a very fast algorithm in Matlab that does the following: I have 2 vectors, A of dimension nx1 and B of dimension nx1. I want to construct C of dimension 2nx1 such that

C(1)=A(1), C(2)=B(1), C(3)=A(2), C(4)=B(2), C(5)=A(3), C(6)=B(3), ... 

I though about

C=[];
for j=1:n
    C=[C; [A(j) B(j)]'];
end

Do you know something faster and more efficient?

Example:

n=9
A=[1 3 5 7 9 11 13 15 17]';
B=[2 4 6 8 10 12 14 16 18]';
C=[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18]';
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
TEX
  • 2,249
  • 20
  • 43

2 Answers2

5

Typically you will want to avoid appending data to an array within a loop like you have written it as this has to re-allocate memory every time through the loop as you expand the variable.

The easiest thing to do would be to convert them both to row vectors using (:).', concatenate them along the first dimension, and then flatten to a column vector using reshape. Because of MATLAB's column-major ordering, this will automatically inter-leave the values of A and B to create C.

C = reshape(cat(1, A(:).', B(:).'), [], 1)

Benchmark

As far as whether this is faster than indexing (@ThP's answer), here is a brief test to benchmark the two.

sizes = round(linspace(100, 10000, 100));

times1 = zeros(size(sizes));
times2 = zeros(size(sizes));

for k = 1:numel(sizes)
    A = rand(sizes(k), 1);
    B = rand(sizes(k), 1);

    times1(k) = timeit(@()combine1(A,B));
    times2(k) = timeit(@()combine2(A,B));
end

figure
plot(sizes, times1)
hold on
plot(sizes, times2)
legend('cat + reshape', 'Indexing')

function C = combine1(A, B)
    C = reshape(cat(1, A(:).', B(:).'), [], 1);
end

function C = combine2(A,B)
    C = zeros(2*numel(A),1);
    C(1:2:end) = A;
    C(2:2:end) = B;
end

enter image description here

Suever
  • 64,497
  • 14
  • 82
  • 101
  • Nice. It would be interesting to compare using `C(2*n,1)=0` as suggested by Luis Mendo – ThP Jun 01 '16 at 17:18
  • @ThP I compared it. Hardly any difference.http://i.imgur.com/1DqE2gc.png – Suever Jun 01 '16 at 17:19
  • 1
    It is just micro optimization, but the following is slightly faster ` C = [A(:).'; B(:).']; C = C(:);` The guess is that it is just a function call (since the different is about constant relative to "cat + reshape"), but if the problem consists of many function calls it may be significant. – patrik Jun 02 '16 at 08:06
3

In matlab, index operations are generally faster than for-loops.
What I would do is first construct a 2nx1 matrix and then use indexing to assign the values:

C = zeros(2*n,1);
C(1:2:end) = A;
C(2:2:end) = B;
Suever
  • 64,497
  • 14
  • 82
  • 101
ThP
  • 2,312
  • 4
  • 19
  • 25