MATLAB Answers

How can I compare numbers for equality within a tolerance in MATLAB 8.0 (R2012b)?

872 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 29 Nov 2012
The ability to compare numeric values to within a tolerance is not available as a built-in function in MATLAB 8.0 (R2012b). 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
isalmost
A similar approach is used by the attached file (see below), which also has a provision for handling NaN values.
  7 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 (1)

Gabor Bekes
Gabor Bekes on 16 Feb 2017
Edited: Gabor Bekes on 16 Feb 2017
You may try using std(). If your values are identical, their deviance should be zero, if not it increases. You can set an upper limit on this to specify tolerance.
  1 Comment
Walter Roberson
Walter Roberson on 16 Feb 2017
for a pair of values, A and B, std([A B]) works out as abs(A - B)/sqrt(2) .
In my opinion, this adds a level of obscurity to the abs(A - B) calculation that is not worth the few keystrokes saved.

Sign in to comment.

Products


Release

R2012b

Community Treasure Hunt

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

Start Hunting!