Loren on the Art of MATLAB

Turn ideas into MATLAB

This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Get Smart, Be Logical! 1

Posted by Loren Shure,

Recently a customer asked me an interesting question about a good way to compute something. Before I sat down to tackle it, I happened to mention the problem to my pal, Sean. And he quickly answered, "max logical". It took me just a moment to realize what he was saying, and it is the answer to the problem. But when I heard it, I heard a person's name "Max Logical", and though I didn't know who that was, I immediately thought of Maxwell Smart, from the 60s tv comedy in the US, called "Get Smart". By General Artists Corporation-GAC-management. [Public domain], via Wikimedia Commons And you can see the precursor to today's mobile phones!

Contents

The Problem

So what's the problem? The customer posed it by way of an example. Given a 3-D array A, generated for this example from a matrix, find the first plane in which some condition is true.
A=[1 2; 3 4]
M = cat(3, A, A+1, A+2, A+3);
A =
     1     2
     3     4
So the function should work like this: IDX = someFunction(M >=5);
IDX = [NaN 4; 3 2]
IDX =
   NaN     4
     3     2
And, the customer wanted this to work for arrays of higher dimensions as well.

The Solution

As I said, I mentioned this to Sean. But I had thought for about 2 seconds about it before and I realized I could do a find on the entire array, as if it were a vector, get the locations and sort them into their proper locations and find the first one in the correct last dimension. And then Sean said "Max Logical". Here's what a great solution looks like.
catdim = 3;
szA = size(A);
[mv,midx] = max(M >= 5,[],catdim);
IDX = NaN(szA);
IDX(mv) = midx(mv)
IDX =
   NaN     4
     3     2
Why/how did this work? Well, I use the condition I want met into function max, and it is logical input, meaning only 0s and 1s. And max returns the index where the first condition is met, and I do this along the final dimension. Then create an array of NaN values, and use logical indexing to update this index matrix. Voila!

Higher Dimensions

Now let's see if it makes sense in higher dimensions. For simplicity, I again will provide a base array in 1 dimension less than I am ultimately looking, so I can construct something for which I can reasonably easily check the result.
A = randi(17, [3 2 1 3]);
catdim = ndims(A)+1
M = cat(catdim, A, A+1, A+2, A+3, A+4);
catdim =
     5
See a slice of M
sliceOfM = M(:,:,:,1)
sliceOfM =
    12     2
    13     4
     8    16
Apply the max, logical indexing to M next.
szA = size(A)
[mv,midx] = max(M >= 13,[],catdim);
IDX = NaN(szA);
IDX(mv) = midx(mv)
szA =
     3     2     1     3
IDX(:,:,1,1) =
     2   NaN
     1   NaN
   NaN     1
IDX(:,:,1,2) =
   NaN     1
     1   NaN
     4   NaN
IDX(:,:,1,3) =
   NaN     1
     1     1
   NaN     1

Have You Embraced Logical Indexing?

I have made several posts over the years on indexing that readers have found helpful. Do you have any interesting logical stories to share? Post them here.

Get the MATLAB code

Published with MATLAB® R2017b

Note

Comments are closed.

1 CommentsOldest to Newest

Sven Holcombe replied on : 1 of 1

I use this type of logic quite a bit – even ended up packaging it into an FEX entry called find_ndim. You’ll be pleased to see it has the same underlying logic – I just ended using an “index” of zero rather than NaN.
I find it most useful when you’ve got an image and you want to find the “left-most” or “right-most” pixels meeting some criteria.