Rowandish
Rowandish

Reputation: 2735

matlab: how to compare two matrices to get the indeces of the elements that differs from one to another

I'm using Matlab with very big multidimensional similar matrices and I'd like to find the differences of between them.

The two matrices have the same size.

Here is an example:

A(:,:,1) =

     1     1     1
     1     1     1
     1     1     1


A(:,:,2) =

     1     1     1
     1     1     1
     1     1     1


A(:,:,3) =

     1     1     1
     1     1     1
     1     1     1


B(:,:,1) =

     1     1    99
     1     1    99
     1     1     1


B(:,:,2) =

     1     1     1
     1     1     1
     1     1     1


B(:,:,3) =

     1     1    99
     1     1     1
     1     1     1

I need a function that give me the indeces of the values that differs, in this example this would be :

output =

     1     3     1
     1     3     3
     2     3     1

I know that I can use functions like find(B~=A) or find(~ismember(B, A)) I don't know how to change their output to the indeces I want.

Thank you all!

Upvotes: 1

Views: 1718

Answers (1)

rayryeng
rayryeng

Reputation: 104464

You almost have it correct! Remember that find finds column major indices of where in your matrix (or vector) the Boolean condition you want to check for is being satisfied. If you want the actual row/column/slice locations, you need to use ind2sub. You would call it this way:

%// To reproduce your problem
A = ones(3,3,3);
B = ones(3,3,3);
B(7:8) = 99;
B(25) = 99;

%// This is what you call
[row,col,dim] = ind2sub(size(A), find(A ~= B));

The first parameter to ind2sub is the matrix size of where you're searching. Since the dimensions of A are equal to B, we can choose either A or B for the first input, and we use size to help us determine the size of the matrix. The second input are the column major indices that we want to access the matrix. These are simply the result of find.

row, col, and dim will give you the rows, columns and slices of which elements in your 3D matrix were not equal. Also note that these will be column vectors, as the output of find will produce a column vector of column-major indices. As such, we can concatenate each of the column vectors into a single matrix and display your information. Therefore:

locations = [row col dim];
disp(locations);

 1     3     1
 2     3     1
 1     3     3

As such, the first column of this matrix tells you the row locations of where the matrix values are unequal, the second column of this matrix tells you the column locations of where the matrix values are unequal, and finally the third column tells you the slices of where the matrix values are unequal. Therefore, we have three points in this matrix that are unequal, which are located at (1,3,1), (2,3,1) and (1,3,3) respectively. Note that this is unsorted due to the nature of find as it searches amongst the columns of your matrix first. If you want to have this sorted like you have in your example output, use sortrows. If we do this, we get:

sortrows(locations)

ans =

     1     3     1
     1     3     3
     2     3     1

Upvotes: 3

Related Questions