3 views (last 30 days)

Show older comments

I'm creating vector with specified increment and later on I'm logical indexing it. When I'm looking for a value that should be present it turns out it's not there. Please explain the issue. What's the proper usage of logical indexing in such case?

x = -3:0.1:3;

any(x == 0.8) % returns 0 - no value 0.8 in -3:0.1:3;

%

x = round(x,1);

any(x == 0.8) % returns 1 - value 0.8 present in -3:0.1:3;

Stephen
on 20 May 2021

"Please explain the issue."

Read about binary floating point numbers:

This is worth reading as well:

"What's the proper usage of logical indexing in such case?"

Do not expect exact equivalence. Do not round.

Compare the absolute difference against a tolerance:

abs(A-B)<tol

Jan
on 20 May 2021

Edited: Jan
on 20 May 2021

Welcme to the world of numerical maths.

Your question belongs to the list of Most Frequently Asked Questions:

"What's the proper usage of logical indexing in such case?"

Never compare floating point numbers by ==, but consider a tolerance. The size of this tolerance cannot be defined in general, see e.g.:

(1e17 + 1 - 1e17) * 1e6 % replies 0

(1e17 - 1e17 + 1) * 1e6 % replies 1e6

The unavoidable numerical rounding errors can be amplified by further calculations. Therefore a scientific calculation must include an analysis of the sensitivity to the initial values and parameters.

Daniel Pollard
on 20 May 2021

I'm struggling a bit to understand exactly what your question is but I think what you're asking is why the value 0.8 is not in your vector x=-3:0.1:3. The answer is that Matlab deals with floating point numbers, so the numbers stored may sometimes be off from what you expect by a very tiny amount.

The workaround, if you know what the precision of you numbers should be, is to round to that precision. Your code is as follows:

x = -3:0.1:3;

You define the vector.

x == round(0.8,1);

This asks Matlab a question. You've asked "what elements of x are exactly equal to round(0.8,1)? You'd expect the response to be a vector of zeros except at 0.8, where you'd expect a 1. This line doesn't actually do anything as you don't store or display the output.

any(x == 0.8); % returns 0 - no value 0.8 in -3:0.1:3;

As you've noted, none of the elements of x are equal to 0.8, despite your expectations that one of them will be.

x = round(x,1);

You now round all the elements of x to one significant figure.

x == round(0.8,1);

Again you ask "Are any elements of x equal to 0.8?", but now one of them is. However again you don't store or display the output so effectively it does nothing.

any(x == 0.8); % returns 1 - value 0.8 present in -3:0.1:3;

Are any of the elements of x equal to 0.8? There wasn't one before, but now there is. This is because of the rounding you did removing the floating point error.

If you want to return the position in x where 0.8 is stored, you can use code something like

x = -3:0.1:3; % Define the vector

x = round(x, 1); % Round all elements in the vector to 1 SF

pos = find(x == 0.8); % pos is the index where x = 0.8;

disp(pos)

disp(x(pos))

Sulaymon Eshkabilov
on 20 May 2021

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!