oarar
oarar

Reputation: 137

Condition execute for different columns in each row

A = [0,0,1,0,1,0,1,0,0,0;
     0,0,0,0,1,0,1,0,0,0;
     0,0,1,0,1,0,1,0,0,0];

B = [2,5;
     1,6;
     3,10];

Expected Output Cell Array:

C = [1,1,1,1;            %// 2-3-4, 3-4-5, 4-5, 5
     0,0,1,1,1,0;        %// 1-2-3, 2-3-4, 3-4-5, 4-5-6, 5-6, 6
     1,1,1,1,1,0,0,0];   %// 3-4-5, 4-5-6, 5-6-7, 7-8-9, 8-9-10, 9-10, 10

Matrix B includes which columns should be used to execute the condition on Matrix A. For example, first row of B is 2 and 5; so elements between 2nd 5th column of matrix A should be used to execute the condition. Second row of B is 1 and 6; so elements between 1st 6th column should be used to execute the condition. And so on...

The condition: if sum of successive 3 elements is bigger than or equal to 1 then write 1 to matrix C; otherwise write 0. For example, A includes 0,1,0 as three successive elements (sum is 0+1+0=1), so write 1 to matrix C. Another example, first three elements of A in second row are 0,0,0 (sum is 0), so write 0 to matrix C. And so on...

"Sometimes it can be considered only 1 or 2 successive elements."

For example, condition execution of first row of A ends with 5th column, so only value 5th column should be considered; which is 1. So 1 is written to matrix C.

Explaining the first row of C:

1, since (sum of 2,3,4 elements of A(1,:)) >= 1

1, since (sum of 3,4,5 elements of A(1,:)) >= 1

since max limit is 5, only 2 successive elements are taken here
1, since (sum of 4,5 elements alone of A(1,:)) >= 1

since max limit is 5, only 1 successive element is taken here
1, since (sum of 5th element alone of A(1,:)) >= 1

Without for loop, only with matrix operations, how can I do this complex task? or any trick?

Upvotes: 0

Views: 68

Answers (1)

Santhan Salai
Santhan Salai

Reputation: 3898

Using mat2cell, cellfun, im2col and any

subMatLen = 3;

%// Converting both A & B matrix to Cell Arrays to perform operations Row-wise
AC = mat2cell(A,ones(1,size(A,1)),size(A,2));
BC = mat2cell(B,ones(1,size(B,1)),size(B,2));

%// Getting only the columns of each rows within the limits specified  by Matrix B
%// Also appended with zeros for my own convenience as it wont affect the 'summing' process
out = cellfun(@(x,y) [x(y(1):y(2)),zeros(1,subMatLen-1)],AC, BC, 'uni', 0);

%// Finally taking each 1x3 sliding sub-matrix and returning 1 if `any` of it is non-zero
%// which is equivalent to summing and checking whether they are >= 1
out = cellfun(@(x) any(im2col(x, [1,subMatLen], 'sliding')), out, 'uni', 0);

Your Sample Input:

A = [0,0,1,0,1,0,1,0,0,0;
     0,0,0,0,1,0,1,0,0,0;
     0,0,1,0,1,0,1,0,0,0];

B = [2,5;
     1,6;
     3,10];

Output:

>> celldisp(out)

out{1} =

 1     1     1     1


out{2} =

 0     0     1     1     1     0


out{3} =

 1     1     1     1     1     0     0     0

If you want them as a single row or column matrix, you could add this to the bottom of the code:

out = cat(2,out{:})

or

out = (cat(2,out{:})).'

Upvotes: 1

Related Questions