Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identify sequences of the same number in a matrix

Tags:

matrix

matlab

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, there are consecutive numbers in it; notice for example the 2 2 2 2 on the first and second row.

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

So for example, for 1: there are three consecutive numbers on the first row and three on 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]

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 counting forward for the consecutive occurrences of a number.

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

like image 321
Febri Dwi Laksono Avatar asked Dec 05 '22 15:12

Febri Dwi Laksono


2 Answers

You can try this:

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);

For this example, there will be 3 submatrices in the variable result.

result = 

    [2x14 double]
    [2x14 double]
    [2x14 double]

To access them, use the following syntax:

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

Then you 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 asked in the comments, A is a 3D matrix, this code works just the same, but the structure of result is a bit different:

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

To access these matrices, use for instance

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
like image 138
H.Muster Avatar answered Jan 09 '23 10:01

H.Muster


Edited because the question changed

This is nowhere near to optimal 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 obtain Matrix2 and Matrix3. If you have something like

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

then you will get

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

so it may not be what you want. It is not clear from your question if this is the case or not, but if not tell me and I will delete the answer

like image 44
mathematician1975 Avatar answered Jan 09 '23 10:01

mathematician1975