# Why two equal columns of two matrices have different means?

I've written a program in which it is necessary to delete some points from a matrix if they exist. sometimes, there are more than one copy of them in the matrix. But the problem is that when it comes to check whether those points are in the matrix, MATLAB can't recognize them in the matrix although thery are exist.

Let's begin from these commands and their echos. In the following, "intersections" function gets the intersection points.

[points(:,1) points(:,2)] = intersections(obj.modifiedVGVertices(1,:), obj.modifiedVGVertices(2,:), ... [vertex1(1) vertex2(1)],[vertex1(2) vertex2(2)]); points vertex1 vertex2 


Their echo:

points =     12.0000   15.0000    33.0000   24.0000    33.0000   24.0000   vertex1 =      12     15   vertex2 =      33     24 


Two points(that are vertex1 and vertex2) should be eliminated from the result. it should be done by the below commands:

points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)),:);  points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)),:); 


After doing that, we have this unexpected outcome:

points =     33.0000   24.0000 


The outcome should be an empty matrix. As you can see, the first(or second?) pair of [33.0000 24.0000] has been eliminated, but not the second one.

Then I checked these two expressions:

points(1) ~= vertex2(1)  ans =       0   points(2) ~= vertex2(2)  ans =       1   <-----It means 24.0000 is not equal to 24.0000? 


What is the problem?

To become more and more surprised, I made a new script that has only these commands:

points = [12.0000   15.0000           33.0000   24.0000           33.0000   24.0000];    vertex1=[12 ;  15];  vertex2=[33 ;  24];    points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)),:);    points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)),:);     points 


The result:

points =
Empty matrix: 0-by-2

Replay

The problem you're having relates to floating point comparison. The numbers differ by very small decimal amounts. You would have to do the comparisons by checking that the values are within some range of one another.

For example:

a = 24;
b = 24.000001;
tolerance = 0.001;
if abs(a-b) < tolerance, disp('Equal!'); end



will display "Equal!".

You could then change your code to something like:

points = points((abs(points(:,1)-vertex1(1)) > tolerance) | ...
(abs(points(:,2)-vertex1(2)) > tolerance),:)



Look at this article: The Perils of Floating Point. Though its examples are in FORTRAN it has sense for virtually any modern programming language, including MATLAB. Your problem (and solution for it) is described in "Safe Comparisons" section.

type

format long g



This command will show the FULL value of the number. It's likely to be something like 24.00000021321 != 24.00000123124

Try writing

0.1 + 0.1 + 0.1 == 0.3.

Warning: You might be surprised about the result!

Maybe the two numbers are really 24.0 and 24.000000001 but you're not seeing all the decimal places.

check out the Matlab EPS function http://matlab.izmiran.ru/help/techdoc/ref/eps.html

Matlab uses floating point math up to 16 digits of precision (only 5 are displayed).

Category: matlab Time: 2009-03-26 Views: 1