How can I compare numbers for equality within a tolerance?

127 views (last 30 days)
I need to compare two numeric matrices. A built-in function such as EQ (==) finds two numbers to be different even they differ by only 1e-15. Therefore, I was looking for another built-in function that could take a tolerance as an input argument, and return “true” when the absolute difference is below the tolerance threshold. How can I do that in MATLAB?

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 13 Sep 2024
Edited: MathWorks Support Team on 13 Sep 2024
If you are using MATLAB R2024b
In MATLAB R2024b, MathWorks introduced a new function "isapprox" which can determine approximate equality using the tolerance threshold, you can find more details of this function in the documentation below
If you are using MATLAB R2015a and later
In MATLAB R2015a, MathWorks introduced the built-in function "ismembertol" which compares members of a set within a tolerance.
For example, you can compare "A" and "B" to determine if their absolute difference is less than 1e-7 by using the following command:
ismembertol(A, B, 1e-7)
For more information about "ismembertol", please see the link below:
If you are using MATLAB R2014b and earlier
The ability to compare numeric values to within a tolerance is not available as a built-in function in MATLAB R2014b and earlier. As a workaround to avoid issues resulting from roundoff error, you can compare the absolute difference of the operands to a tolerance. Instead of:
A==B
you can use the following:
abs(A-B) < 1e4*eps(min(abs(A),abs(B)))
There are also a couple of entries for this on the MATLAB Central file exchange. These files are not produced by or supported by MathWorks, so any questions should be directed to the authors, however other customers have found these to be useful.
"IsNear" function:
"isalmost" function:
A similar approach is used by the attached file (see below), which also has a provision for handling NaN values.
  5 Comments
Walter Roberson
Walter Roberson on 11 Aug 2021
No.
Suppose you take
format long g
F = 10;
A1 = 1/F;
A2 = A1*(1+eps);
C1 = 0; C2 = 0;
N = F;
for K = 1 : N
C1 = C1 + A1;
C2 = C2 + A2;
end
algebraically_expected = N/F
algebraically_expected =
1
low_side = C1
low_side =
1
high_side = C2
high_side =
1
low_difference = low_side - algebraically_expected
low_difference =
-1.11022302462516e-16
high_difference = high_side - algebraically_expected
high_difference =
6.66133814775094e-16
high_side - low_side
ans =
7.7715611723761e-16
A2-A1
ans =
2.77555756156289e-17
(A2-A1)*F
ans =
2.77555756156289e-16
That last tells you that if you were to have algebrically perfect additions, then with A2 being larger than A1, you would expect 2.7E-16 difference between F additions of A2 compared to F additions of A1. But high_side - low_side shows that in reality you get an error about 3 1/2 times as large.
So errors in representation accumulate, and they can accumulate more than is at first obvious. If you do N calculations, the accumulated error might be more than N times the individual error.
Therefore, when you are comparing floating point numbers, it is not typically a good idea to use (individual error times number of operations) as the tolerance, and to instead use a multiple of that. But what multiple?
The multiple that is "reasonable" depends upon the kind of operations being done. If you are just doing additions, then the multiple might be rather small. If you are doing matrix operations then you should think about the "condition number".
I did run into a situation a couple of weeks ago in which a multiple of about 5000*eps was appropriate; I know I posted the code, but unfortunately my memory is not giving me enough context to find it at this time.

Sign in to comment.

More Answers (0)

Categories

Find more on Entering Commands in Help Center and File Exchange

Products


Release

R2024b

Community Treasure Hunt

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

Start Hunting!