From: Ross Anderson on
Say I have [a] that is 100 by 100 by 3. Looking at it from one side it is 100x100. The left side of this view is 100x3. What if I want to find the first layer from the left that is not equal to a given 100x3 matrix? In 1d I can say ind=find(x~=3), in 2d, [dummy ind]=ismember(x,[1 2 3],'rows'), but in 3d, what would I do?

For simply finding nonzero elements in an n-D matrix, this post on the newsreader shows how:
a=zeros(4,4,4,4);
a(1,4,2:3,3)=1;
lix=find(a);
clear r;
[r{1:ndims(a)}]=ind2sub(size(a),lix);
r=cat(2,r{:})
result:
r =
1 4 2 3
1 4 3 3

This is for a~=0, but what if I want to extend this to find a particular matrix, like find the first layer from the left in [a] that is not equal to a given 100x3 matrix, or the last layer from the top in [a] that is not equal to some 3x100 matrix? In other words, for 1d, find(a~=0), but what about for a in 3d, find(a~=[some 2-D matrix],'first', 'from the left')? Coding this up in a tidy for loop is certainly possible, but perhaps one of you has a more elegant idea?
From: dpb on
Ross Anderson wrote:
> Say I have [a] that is 100 by 100 by 3. Looking at it from one side it
> is 100x100. The left side of this view is 100x3. What if I want to find
> the first layer from the left that is not equal to a given 100x3 matrix?
> In 1d I can say ind=find(x~=3), in 2d, [dummy ind]=ismember(x,[1 2
> 3],'rows'), but in 3d, what would I do?

Loop over the planes and simply return index of match or equality.

function idx = firstmatch(x,y)
idx = 0; % no match explicitly set
for i=1:3
if isequal(x,y(:,:,i))
idx = i;
break
end
end

....

Don't need the overhead of find() here for the purpose it would seem.
Not the isequal() function for arrays (roughly equivalent to all(x==y)
if not precisely implemented that way for matching arrays). Note the
above has no error checking for such things as mismatched array sizes,
etc., ...

--
From: dpb on
dpb wrote:
> Ross Anderson wrote:
>> Say I have [a] that is 100 by 100 by 3. Looking at it from one side it
>> is 100x100. The left side of this view is 100x3. What if I want to
>> find the first layer from the left that is not equal to a given 100x3
>> matrix? In 1d I can say ind=find(x~=3), in 2d, [dummy
>> ind]=ismember(x,[1 2 3],'rows'), but in 3d, what would I do?
>
> Loop over the planes and simply return index of match or equality.
>
> function idx = firstmatch(x,y)
> idx = 0; % no match explicitly set
> for i=1:3
> if isequal(x,y(:,:,i))
> idx = i;
> break
> end
> end
>

OBTW...

The above was written for the planes; you're example was going across
making planes along each set of columns, sorry.

Pass direction or use some logic to find the corresponding shape
agreement. Also, use the size() function of proper orientation to
control the loop iteration.

--