Check element wise equality of a 3D matrix Matlab

2019-07-23 17:08发布

问题:

I have a 3D matrix say for eg. A(10x5x8). I need to get a 2D matrix (Boolean) out of it of size 10x5.

True if its elemental 3 Dimensional values are all same. i.e. Result(1,1) = 1 if A(1,1,1) == A(1,1,2) == A(1,1,3) etc..

False if at least one is different.

I expect a vectored approach which is fast and efficient.

Sample input:

A(:,:,1) = 1 2
           2 2
A(:,:,2) = 1 1
           2 3

Expected Output:

Result = 1 0
         1 0

回答1:

Use bsxfun with the eq function and use the first slice as the first input and compare with the other slices for the second input. Allow the first input to broadcast itself over the multiple slices.

Once you do that, use all and check the third dimension:

ind1 = bsxfun(@eq, A(:,:,1), A(:,:,2:end);
ind2 = all(ind1, 3);

The logic behind the above is very simple. How the first line of code works is that you would create a temporary matrix that would take the first slice of A and let it duplicate itself for as many slices as you have in A, without the first slice. Once you do this, you would do an element-by-element equality with this temporary matrix and the other slices. If you had a 3D column that was all equal, the one element from the first slice would be compared with every single value that corresponds to the same 3D column. Should they all equal to each other, then you would get a 3D column of all logical 1s. Therefore, to have a 3D column that is all equal to each other, all of the values should be 1, which is why all is used - to check if all values in a 3D column are equal to 1. Should all of the 3D column be a logical 1, we have matched your criteria.

Example run

>> A1 = [1 2; 2 2];
>> A2 = [1 1; 2 3];
>> A3 = [1 3; 2 4];
>> A4 = [1 5; 2 6];
>> A = cat(3, A1, A2, A3, A4);    
>> ind1 = bsxfun(@eq, A(:,:,1), A(:,:,2:end);
>> ind2 = all(ind1, 3)

ind2 =

     1     0
     1     0

I made a matrix of 4 slices where the 3D column at the top left corner and the bottom left corner have all of the same values. Once you run through the code at the beginning of the post, we get what you expect.



回答2:

Here's with short and sweet diff and must be quite memory efficient -

out = ~any(diff(A,[],3),3)

So, basically with diff along the third dimension diff(..[],3), you would calculate differences between the same (i,j) but on different 3D slices. Thus, if all such diff outputs are zeros, that would indicate that all dim3 elements for the same (i,j) are the same. This all zeros information is then picked up by ~any() also along dim3 with ~any(.,3) for the desired 2D array output.