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
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.
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.