Star
Star

Reputation: 2299

Alternating chunks of a vector in Matlab

I have two vectors in Matlab A and B.

I want to construct a vector C where I alternate chunks of A and B where a chunk consists of a nonzero element and all the preceding 0's back to the previous nonzero element.

For example

A=[1 2 0 3 0 4 0 0 0 5]; %in chunks: {1}{2}{0 3}{0 4}{0 0 0 5} 
B=[6 7 8 9 10 11 0 12 0 0]; %in chunks: {6}{7}{8}{9}{10}{11}{0 12} 
C=[1 6 2 7 0 3 8 0 4 9 0 0 0 5 10];

or, another example

A=[0 0 4 9 9 9]; %in chunks: {0 0 4}{9}{9}{9}
B=[0 1 0 0 3 4 3 0 9 0 1 1 1]; %in chunks: {0 1}{0 0 3}{4}{3}{0 9}{0 1 1} 
C=[0 0 4 0 1 9 0 0 3 9 4 9 3];

Could you help me to develop the code?

Upvotes: 0

Views: 121

Answers (3)

geoinformatic
geoinformatic

Reputation: 166

[~, posA] = find(A)
posA = [0,posA]
clear A_
for i = 1:length(posA)-1
    A_(i) = {A(posA(i)+1:posA(i+1))}
end

[~, posB] = find(B)
posB = [0,posB]
clear B_
for i = 1:length(posB)-1
    B_(i) = {B(posB(i)+1:posB(i+1))}
end

clear C_
for i = 1:min(length(A_), length(B_))
    C_(i) = {{A_{1,i},B_{1,i}}};
end
C = cell2mat([C_{:}])

Upvotes: 0

Lior
Lior

Reputation: 2019

Here is a way of doing it without for loops:

A=[0 0 4 9 9 9];
B=[0 1 0 0 3 4 3 0 9 0 1 1 1];

% Find indices where chunks end.
indsA = find(A~=0);
indsB = find(B~=0);

% Remove trailing zeros, since they are not part of any chunk.
A = A(1:indsA(end));
B = B(1:indsB(end));

% Get cell array of chunks. Use difference between successive last indices 
% of chunks to get the chunk sizes. Add a 0 dummy index to get the first
% chunk size.
chuncksA = mat2cell(A,1,diff([0,indsA]));
chuncksB = mat2cell(B,1,diff([0,indsB]));

% To take alternating chunks from each vector, we need to make sure we have
% an equal amount of chunks from each vector. This amount will be stored in 
% sz
sz = min(numel(chuncksA),numel(chuncksB));

% Sort the chunks by alternation, by combining the cell arrays on on top of
% the other, and then turning them into a column array by column-major 
% ordering
chuncks = [chuncksA(1:sz);chuncksB(1:sz)];
chuncks = chuncks(:)';

% convert back to vector
C = cell2mat(chuncks)

I suggest you test whether using this approach is faster or slower on your data.

Upvotes: 4

Saeed Masoomi
Saeed Masoomi

Reputation: 1834

clc
clear

A=[0 0 4 9 9 9];                         % input1
B=[0 1 0 0 3 4 3 0 9 0 1 1 1];    % input2
a=length(A);                               % number of element in A
b=length(B);                               % number of element in B
count1=0;                                   % select data from A
count2=0;                                  % select data from B
c=[];                                           % for append data
while a >0 && b>0
   count1=count1+1;
   count2=count2+1;
   if(a>0)            
      if(A(count1)~=0)
         c=[c A(count1)];
      else
         c=[c A(count1)];
         count1=count1+1;
         while(a>0 &&A(count1)==0)   % for repeated zeros i use while
            c=[c A(count1)];
            a=a-1;
            count1=count1+1;
         end
         if(a>0)
            c=[c A(count1)];
            a=a-1;
         end
     end
 end
 if(b>0)
    if(B(count2)~=0)
        c=[c B(count2)];
    else
        c=[c B(count2)];
        count2=count2+1;
        while(b>1 && B(count2)==0)
            c=[c B(count2)];
            b=b-1;
            count2=count2+1;
        end
        if(b>0)
            c=[c B(count2)]; %#ok<*AGROW>
            b=b-1;
         end
     end
  end
  a=a-1;
  b=b-1;
end
disp('C=')
disp(c)

Upvotes: 1

Related Questions