Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Replacing `find` with logical indexing

Subject: Replacing `find` with logical indexing

From: Jeff

Date: 10 Jul, 2013 00:44:11

Message: 1 of 7

I am trying to find the smallest nonzero magnitude element of a vector, D. Note that D is not integers. I am eliminating nonzero entries using the `find` command (first line below). The editor says to replace `find` with logical indexing, but replacing `D(find(D))` with `D(D)` returns an error. This is not slowing my code very much, but the editor's warning is mildly bothersome. How do I use logical indexing to fix this?

    nonZeroD = abs(D(find(D)));
    lambda = max(nonZeroD(nonZeroD == min(nonZeroD)));
    ICmode = find(D==lambda, 1, 'first');

I also note that the editor doesn't complain about the second `find`.

Subject: Replacing `find` with logical indexing

From: dpb

Date: 10 Jul, 2013 01:20:34

Message: 2 of 7

On 7/9/2013 7:44 PM, Jeff wrote:
> I am trying to find the smallest nonzero magnitude element of a vector,
> D. Note that D is not integers. I am eliminating nonzero entries using
> the `find` command (first line below). The editor says to replace `find`
> with logical indexing, but replacing `D(find(D))` with `D(D)` returns an
> error. This is not slowing my code very much, but the editor's warning
> is mildly bothersome. How do I use logical indexing to fix this?
>
> nonZeroD = abs(D(find(D)));

nonZeroD = abs(D(D~-0));

> lambda = max(nonZeroD(nonZeroD == min(nonZeroD)));
> ICmode = find(D==lambda, 1, 'first');
>
> I also note that the editor doesn't complain about the second `find`.

Depends on what's done w/ the result. In the second you're using the
truncated version of returning only the first position so logical
addressing doesn't work so cleanly.

I'm not absolutely positive I follow what you're trying to do but why
isn't it just

DNZmin=min(abs(D(D~-0))); % ?

What's the point of the max(DNZ(DNZ==min(DNZ)))? If you've only
collected terms in the vector ==min(vector), then the max is the min by
that selection process.

--

Subject: Replacing `find` with logical indexing

From: Jeff

Date: 10 Jul, 2013 02:19:07

Message: 3 of 7

dpb <none@non.net> wrote in message <krict2$9cb$1@speranza.aioe.org>...
> On 7/9/2013 7:44 PM, Jeff wrote:
> > I am trying to find the smallest nonzero magnitude element of a vector,
> > D. Note that D is not integers. I am eliminating nonzero entries using
> > the `find` command (first line below). The editor says to replace `find`
> > with logical indexing, but replacing `D(find(D))` with `D(D)` returns an
> > error. This is not slowing my code very much, but the editor's warning
> > is mildly bothersome. How do I use logical indexing to fix this?
> >
> > nonZeroD = abs(D(find(D)));
>
> nonZeroD = abs(D(D~-0));
Is that supposed to be abs(D(D~=0))? I get an error using D~-0.
>
> > lambda = max(nonZeroD(nonZeroD == min(nonZeroD)));
> > ICmode = find(D==lambda, 1, 'first');
> >
> > I also note that the editor doesn't complain about the second `find`.
>
> Depends on what's done w/ the result. In the second you're using the
> truncated version of returning only the first position so logical
> addressing doesn't work so cleanly.
>
> I'm not absolutely positive I follow what you're trying to do but why
> isn't it just
>
> DNZmin=min(abs(D(D~-0))); % ?
Yes, it is just that. You find the indexes of the nonzero positions, select those values of D, take the absolute value, and take the minimum. That's what I was trying to do.
>
> What's the point of the max(DNZ(DNZ==min(DNZ)))? If you've only

Hmm. Good question. I developed this code slowly and at one point it was returning multiple values (if there was a tie for smallest absolute value). That code might be an artifact of me trying to get only one result out. It does look redundant to me.

> collected terms in the vector ==min(vector), then the max is the min by
> that selection process.
>
> --

Subject: Replacing `find` with logical indexing

From: TideMan

Date: 10 Jul, 2013 02:24:13

Message: 4 of 7

On Wednesday, July 10, 2013 1:20:34 PM UTC+12, dpb wrote:
> On 7/9/2013 7:44 PM, Jeff wrote:
>
> > I am trying to find the smallest nonzero magnitude element of a vector,
>
> > D. Note that D is not integers. I am eliminating nonzero entries using
>
> > the `find` command (first line below). The editor says to replace `find`
>
> > with logical indexing, but replacing `D(find(D))` with `D(D)` returns an
>
> > error. This is not slowing my code very much, but the editor's warning
>
> > is mildly bothersome. How do I use logical indexing to fix this?
>
> >
>
> > nonZeroD = abs(D(find(D)));
>
>
>
> nonZeroD = abs(D(D~-0));
>
>
>
> > lambda = max(nonZeroD(nonZeroD == min(nonZeroD)));
>
> > ICmode = find(D==lambda, 1, 'first');
>
> >
>
> > I also note that the editor doesn't complain about the second `find`.
>
>
>
> Depends on what's done w/ the result. In the second you're using the
>
> truncated version of returning only the first position so logical
>
> addressing doesn't work so cleanly.
>
>
>
> I'm not absolutely positive I follow what you're trying to do but why
>
> isn't it just
>
>
>
> DNZmin=min(abs(D(D~-0))); % ?
>
>
>
> What's the point of the max(DNZ(DNZ==min(DNZ)))? If you've only
>
> collected terms in the vector ==min(vector), then the max is the min by
>
> that selection process.
>
>
>
> --

Oh dpb, what a dreadful typist you are.......
It should be ~=, not ~-:
DNZmin=min(abs(D(D~=0)));

And with floating point numbers, shouldn't it be:
DNZmin=min(abs(D(abs(D)>tol)));
where tol is a small number like 1e-6

Subject: Replacing `find` with logical indexing

From: dpb

Date: 10 Jul, 2013 03:29:51

Message: 5 of 7

On 7/9/2013 9:24 PM, TideMan wrote:
> On Wednesday, July 10, 2013 1:20:34 PM UTC+12, dpb wrote:
...

>>> ... How do I use logical indexing to fix this?

>>> nonZeroD = abs(D(find(D)));

>> nonZeroD = abs(D(D~-0));
>>
...

>> I'm not absolutely positive I follow what you're trying to do but why
>> isn't it just
>>
>> DNZmin=min(abs(D(D~-0))); % ?
>>
>> What's the point of the max(DNZ(DNZ==min(DNZ)))? If you've only
>> collected terms in the vector ==min(vector), then the max is the min by
>> that selection process.
>>
...

> Oh dpb, what a dreadful typist you are.......
> It should be ~=, not ~-:
> DNZmin=min(abs(D(D~=0)));

Indeed, my typing has gotten worse and worse... :( Doesn't help that my
eyes are as well so the differences between = and - and { and (, etc.,
aren't so obvious as once were...

> And with floating point numbers, shouldn't it be:
> DNZmin=min(abs(D(abs(D)>tol)));
> where tol is a small number like 1e-6

Actually, I started to write about that one, but in this case it's not a
problem since the comparison is to the min() of the values in the same
vector. It's the same value identically being compared to.

If in the original code the lambda in the comparison were some other fp
value, then your recommendation/concern is right on. But in the actual
code lambda is min() of of the same vector so it's identical by that
process of selection already and the existence of a value off by only
LSB in the mantissa if it were to exist is already out, anyway. But the
missed comparison of a value entered at the keyboard trying to compare
to one computed internally as is so often the cause of the FAQ question
doesn't arise here.

--

Subject: Replacing `find` with logical indexing

From: Jeff

Date: 10 Jul, 2013 14:55:21

Message: 6 of 7

dpb <none@non.net> wrote in message <krikfe$o13$1@speranza.aioe.org>...
> On 7/9/2013 9:24 PM, TideMan wrote:
> > On Wednesday, July 10, 2013 1:20:34 PM UTC+12, dpb wrote:
> ...
> > And with floating point numbers, shouldn't it be:
> > DNZmin=min(abs(D(abs(D)>tol)));
> > where tol is a small number like 1e-6
>
> ...
>
> If in the original code the lambda in the comparison were some other fp
> value, then your recommendation/concern is right on. But in the actual
> code lambda is min() of of the same vector so it's identical by that
> process of selection already and the existence of a value off by only
> LSB in the mantissa if it were to exist is already out, anyway. But the
> missed comparison of a value entered at the keyboard trying to compare
> to one computed internally as is so often the cause of the FAQ question
> doesn't arise here.
>
Isn't TideMan right? The inner parenthesis comparison, D~=0, is comparing floating point numbers in D to 0. If there is a very, very small value of D, say 1e-20, which really should be zero, I don't want that value returned. In your case, since I didn't specify how D was created, shouldn't you have included that?

FYI: D is created as follows:
for jj = 1:N
  for kk = 1:N
    idxVal = (jj-1)*N + k;
    D(idxVal)=4-2*cosd((jj*180)/(N+1)) - 2*cosd((kk*180)/(N+1));
  end
end

N is an integer, power of 2, at least 8 (e.g., 8, 16, 32,...). I'm pretty sure I can get away with D~=0, but I'm curious how you knew that without knowing D.

Subject: Replacing `find` with logical indexing

From: dpb

Date: 10 Jul, 2013 17:47:02

Message: 7 of 7

On 7/10/2013 9:55 AM, Jeff wrote:
...

> ... The inner parenthesis comparison, D~=0, is
> comparing floating point numbers in D to 0. If there is a very, very
> small value of D, say 1e-20, which really should be zero, I don't want
> that value returned. In your case, since I didn't specify how D was
> created, shouldn't you have included that?

Well, if that is the issue then yes. I presumed that ~=0 was intended
to be that by design/intent.

If you're indeed trying to exclude for some tolerance then indeed you do
need to make the comparison based on that.

Whether that's a constant or a percentage of the magnitude or just what
it is then is dependent upon the objectives.

--

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us