tags:

views:

709

answers:

6

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
+15  A: 

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),:)
gnovice
why can't I see that small decimal amount?
Kamran
you can see it if you view the variable in the matrix view. Right click on variable -> "View selection" or something? I don't have MATLAB here, so I can't check.
atsjoo
You can also see small differences by typing "format long" at the command prompt.
gnovice
matlab has about 16 digits of precision... only displays 5 unless you do the above
jle
thanks..very helpful :)
Kamran
you are right:format longpoints = 12.000000000000000 15.000000000000000 33.000000000000000 23.999999999999996 33.000000000000000 24.000000000000000
Kamran
"format hex" can sometimes help even more than format long here.
Sam Roberts
A: 

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

Jimmy J
+7  A: 

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.

Rorick
+1: Good link. I was looking around for one, but you beat me to it. =)
gnovice
I discovered it some time ago and was very impressed with it =) Now I always recommend it in similar situations.
Rorick
A: 

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).

jle
+1  A: 

This has also been addressed here

ChrisF
+3  A: 

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

KitsuneYMG

related questions