Determine sequences of the same number in a matrix

I have matrix A

A= [0 0 2 2 2 2 0 0 1 1 1 0 3 3; 2 2 2 2 0 0 1 1 1 0 0 3 3 0; 

As you can see, it has consecutive numbers; notice, for example, 2 2 2 2 on the first and second lines.

For each number present in this matrix (or at least for each number from 1 to the maximum number in my matrix), I want to have an output matrix that indicates the sequences of this number and this number only in the original matrix.

So, for example, for 1 : in the first row there are three consecutive numbers and three in the second row: I want to indicate this in the first output matrix as follows:

 Matrix 1 = [ 0 0 0 0 0 0 0 0 1 2 3 0 0 0; 0 0 0 0 0 0 0 1 2 3 0 0 0 0] 

The same for number 2 :

 Matrix 2 = [ 0 0 1 2 3 4 0 0 0 0 0 0 0 0; 1 2 3 4 0 0 0 0 0 0 0 0 0 0] 

and 3 :

 Matrix 3 = [ 0 0 0 0 0 0 0 0 0 0 0 0 1 2; 0 0 0 0 0 0 0 0 0 0 0 1 2 0] 

As you can see, each output matrix shows forward counting for consecutive occurrences of a number.

So, in this case, I have 3 output matrices, because matrix A has 3 as the largest value.

+4
source share
3 answers

You can try the following:

 A= [0 0 2 2 2 2 0 0 1 1 1 0 3 3; 2 2 2 2 0 0 1 1 1 0 0 3 3 0]; result = arrayfun(@(b) (A == b).*cumsum((A == b),2),nonzeros(unique(A)), 'UniformOutput', false); 

In this example, the variable result will be 3 submatrices.

 result = [2x14 double] [2x14 double] [2x14 double] 

To access them, use the following syntax:

 result{1} result{2} result{3} 

Then you will get:

 ans = 0 0 0 0 0 0 0 0 1 2 3 0 0 0 0 0 0 0 0 0 1 2 3 0 0 0 0 0 ans = 0 0 1 2 3 4 0 0 0 0 0 0 0 0 1 2 3 4 0 0 0 0 0 0 0 0 0 0 ans = 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 1 2 0 

~ ~ edit
If, as indicated in the comments, A is a three-dimensional matrix, this code works the same, but the structure of the result is slightly different:

 result = [2x14x2 double] [2x14x2 double] [2x14x2 double] 

To access these matrices, use, for example,

 result{1}(:,:,1) % for the results of comparing A(:,:,1) with value 1 result{1}(:,:,2) % for the results of comparing A(:,:,2) with value 1 
+8
source

Edited because the question has changed

This does not approach the optimum, but will do what you want

  V = 1; C = A' == V; D = cumsum(C).*C E = D' 

now E will be Matrix1 in your example. Change V to 2 and 3 to get Matrix2 and Matrix3 . If you have something like

  A = [2 2 2 0 0 0 0 0 2 2 2] 

then you get

  [1 2 3 0 0 0 0 0 4 5 6] 

perhaps this is not what you want. From your question it is not clear if this is so or not, but if you do not tell me, I will delete the answer

+4
source

This is a loop based solution to get you started:

 A = [ 0 0 2 2 2 2 0 0 1 1 1 0 3 3; 2 2 2 2 0 0 1 1 1 0 0 3 3 0 ]; mx = max(A(:)); AA = cell(mx,1); for num=1:mx AA{num} = zeros(size(A)); for r=1:size(A,1) idx = ( A(r,:) == num ); AA{num}(r,idx) = sum(idx):-1:1; end end 

Result:

 >> AA{1} ans = 0 0 0 0 0 0 0 0 3 2 1 0 0 0 0 0 0 0 0 0 3 2 1 0 0 0 0 0 >> AA{2} ans = 0 0 4 3 2 1 0 0 0 0 0 0 0 0 4 3 2 1 0 0 0 0 0 0 0 0 0 0 >> AA{3} ans = 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 2 1 0 

EDIT:

Updated code for working with a matrix with three dimensions:

 A = zeros(2,7,2); A(:,:,1) = [2 2 2 0 0 1 1 ; 0 0 2 2 2 1 1]; A(:,:,2) = [1 1 2 2 2 0 0 ; 0 1 1 0 2 2 2]; mx = max(A(:)); AA = cell(mx,1); for num=1:mx AA{num} = zeros(size(A)); for p=1:size(A,3) for r=1:size(A,1) idx = ( A(r,:,p) == num ); AA{num}(r,idx,p) = 1:sum(idx); end end end 

Result:

 %# contains consecutive numbers corresponding to number 1 in all slices >> AA{1} ans(:,:,1) = 0 0 0 0 0 1 2 0 0 0 0 0 1 2 ans(:,:,2) = 1 2 0 0 0 0 0 0 1 2 0 0 0 0 %# contains consecutive numbers corresponding to number 2 in all slices >> AA{2} ans(:,:,1) = 1 2 3 0 0 0 0 0 0 1 2 3 0 0 ans(:,:,2) = 0 0 1 2 3 0 0 0 0 0 0 1 2 3 
+4
source

All Articles