Thread Subject: strange FIND

Subject: strange FIND

From: Stanislav Pospisil

Date: 8 Jul, 1999 16:22:39

Message: 1 of 12

Hi all,

how could someone explain following strange behaviour of FIND
function.

I have

z=1:.1:300

and

find(z==0.6*108)

gives me an empty matrix. Why?

Thanks

--
Stanislav Pospisil
ITAM CAS
Prosecka 76, Prague 9, 19000
Czech republic
tel: 00420-2-882334
fax:00420-2-884634
e-mail:pospisil@itam.cas.cz

Subject: strange FIND

From: didier@Glue.umd.edu (Didier A. Depireux)

Date: 8 Jul, 1999 14:48:44

Message: 2 of 12

Stanislav Pospisil (pospisil@linux.itam.cas.cz) wrote:

: find(z==0.6*108)

It's a rounding error. Look at

>> z(639)
ans =
   64.8000
>> z(639)-64.8
ans =
   1.4211e-14

whereas
>> 0.6*108
ans =
   64.8000
>> 0.6*108-64.8
ans =
     0


Didier

--
Didier A Depireux didier@isr.umd.edu
Neural Systems Lab http://www.isr.umd.edu/~didier
Institute for Systems Research Phone: 301-405-6557 (off)
University of Maryland -6596 (lab)
College Park MD 20742 USA Fax: 1-301-314-9920

Subject: strange FIND

From: Ionel Simionescu

Date: 8 Jul, 1999 17:29:00

Message: 3 of 12


Stanislav Pospisil <pospisil@linux.itam.cas.cz> wrote in message
news:3784B42F.34439C6D@linux.itam.cas.cz...
> Hi all,
>
> how could someone explain following strange behaviour of FIND
> function.
>
> I have
>
> z=1:.1:300
>
> and
>
> find(z==0.6*108)
>
> gives me an empty matrix. Why?
>
> Thanks

I've checked the strange behavior:

» z(639)
ans =
   64.8000
» .6*108
ans =
   64.8000
» z(639) == .6*108
ans =
     0

The problem is NOT with FIND, but with the round-off errors involved by the
':' operator.

After:
» format long

, one can see that:

» z(639)
ans =
  64.80000000000001
» .6*108
ans =
  64.80000000000000

Hey, MATHWORKS?

ionel

Subject: strange FIND

From: Steve Eddins

Date: 8 Jul, 1999 13:40:28

Message: 4 of 12

"Ionel Simionescu" <ionel@psy.uva.nl> writes:

> Stanislav Pospisil <pospisil@linux.itam.cas.cz> wrote in message
> news:3784B42F.34439C6D@linux.itam.cas.cz...
> > Hi all,
> >
> > how could someone explain following strange behaviour of FIND
> > function.
> >
> > I have
> >
> > z=1:.1:300
> >
> > and
> >
> > find(z==0.6*108)
> >
> > gives me an empty matrix. Why?
> >
> > Thanks
>
> I've checked the strange behavior:
>
> » z(639)
> ans =
> 64.8000
> » .6*108
> ans =
> 64.8000
> » z(639) == .6*108
> ans =
> 0
>
> The problem is NOT with FIND, but with the round-off errors involved by the
> ':' operator.
>
> After:
> » format long
>
> , one can see that:
>
> » z(639)
> ans =
> 64.80000000000001
> » .6*108
> ans =
> 64.80000000000000
>
> Hey, MATHWORKS?

Hey! How are ya? ;-)

The "real" problem is that the real number 64.8 has no exact
representation using a binary floating-point format. Use "format
hex" to see one more representation of what's going on.

>> format hex
>> z(639)

ans =

   4050333333333334

>> .6*108

ans =

   4050333333333333

*Neither* of these representations corresponds exactly to 64.8. One
is slightly less than 64.8; the other is slightly greater than 64.8.


It is usually taught early in engineering or scientific programming
courses to avoid testing floating-point numbers for exact equality,
unless you know they are integers. This holds for working with
floating-point numbers in any language; it isn't particular to MATLAB.

Regards,

Steve

--
Steve Eddins
The MathWorks, Inc.
eddins@mathworks.com
http://www.mathworks.com

Subject: strange FIND

From: Scott Coutts

Date: 9 Jul, 1999 10:44:12

Message: 5 of 12

>
> > » z(639)
> > ans =
> > 64.80000000000001
> > » .6*108
> > ans =
> > 64.80000000000000
> >
> > Hey, MATHWORKS?
>
> Hey! How are ya? ;-)
>
> The "real" problem is that the real number 64.8 has no exact
> representation using a binary floating-point format. Use "format
> hex" to see one more representation of what's going on.
>
> >> format hex
> >> z(639)
>
> ans =
>
> 4050333333333334
>
> >> .6*108
>
> ans =
>
> 4050333333333333
>
> *Neither* of these representations corresponds exactly to 64.8. One
> is slightly less than 64.8; the other is slightly greater than 64.8.
>
> It is usually taught early in engineering or scientific programming
> courses to avoid testing floating-point numbers for exact equality,
> unless you know they are integers. This holds for working with
> floating-point numbers in any language; it isn't particular to MATLAB.
>
> Regards,
>
> Steve
>
> --
> Steve Eddins
> The MathWorks, Inc.
> eddins@mathworks.com
> http://www.mathworks.com

Steve,

This is an interesting problem and I find your response to be a little
condescending. The strength of Matlab is that it permits engineers and scientists
from fields _other than_computer_science_ to solve problems effectively. It
should not be compared to languages used mainly by software professionals. A
Matlab user should not be forced to understand the inner workings of the computer
to the level of detail you suggest. If my Matlab scripts asks if 64.8 is equal to
64.8 then the result should be true, especially when the script is using only one
digit after the decimal point as in the original example. In the example you cite
4050333333333334 is compared to 4050333333333333 with a false result. At first
glance, it would seem that a simple solution would be for Matlab to drop the
least significant hex digit when doing floating point comparisons.

Regards,
Scott Coutts

Subject: strange FIND

From: schwarz@kodak.com (Doug Schwarz)

Date: 8 Jul, 1999 23:03:53

Message: 6 of 12

In article <37867B3B.BCBF49CC@ll.mit.edu>, scoutts@ll.mit.edu wrote:

>Steve,
>
>This is an interesting problem and I find your response to be a little
>condescending.

I thought Steve was rather restrained given that this question comes up
just about every week and this time slightly rudely.


>The strength of Matlab is that it permits engineers and scientists
>from fields _other than_computer_science_ to solve problems effectively. It
>should not be compared to languages used mainly by software professionals. A
>Matlab user should not be forced to understand the inner workings of the
computer
>to the level of detail you suggest.

Yes, he or she should. The problem has nothing to do with the language
used, rather it is a consequence of how floating point numbers are
represented in the hardware. It's just a matter of understanding your
tools. I don't need a degree in electrical engineering to understand how
to use a voltmeter and I don't need a degree in computer science to
understand floating point numbers (though misuse of a voltmeter is
potentially more dangerous (pun intended) than misuse of floating point
numbers).


>If my Matlab scripts asks if 64.8 is equal to
>64.8 then the result should be true, especially when the script is using
only one
>digit after the decimal point as in the original example. In the example
you cite
>4050333333333334 is compared to 4050333333333333 with a false result. At first
>glance, it would seem that a simple solution would be for Matlab to drop the
>least significant hex digit when doing floating point comparisons.

Frankly, I'm shocked (there I go again) by your suggestion. First of all,
the errors can easily be greater than the least significant hex digit.
Secondly, it is not up to MATLAB to make such decisions -- it must be done
by the programmer. I'm sorry, but there is just no substitute for knowing
what you're doing.

Perhaps The MathWorks should start printing the following warning on the
MATLAB manuals: "Users are strongly advised to have some idea as to how
computers deal with floating point numbers before attempting to use this
software."

>Regards,
>Scott Coutts

--
Doug Schwarz
Eastman Kodak Company
schwarz@kodak.com

Subject: strange FIND

From: eddins@mathworks.com

Date: 8 Jul, 1999 23:22:40

Message: 7 of 12

Scott Coutts <scoutts@ll.mit.edu> writes:

> This is an interesting problem and I find your response to be a little
> condescending.

Rereading my original post, I see how it could be taken that way. I
sincerely apologize, for I meant no slight.

> The strength of Matlab is that it permits engineers and scientists
> from fields _other than_computer_science_ to solve problems effectively. It
> should not be compared to languages used mainly by software professionals. A
> Matlab user should not be forced to understand the inner workings of the computer
> to the level of detail you suggest. If my Matlab scripts asks if 64.8 is equal to
> 64.8 then the result should be true, especially when the script is using only one
> digit after the decimal point as in the original example. In the example you cite
> 4050333333333334 is compared to 4050333333333333 with a false result. At first
> glance, it would seem that a simple solution would be for Matlab to drop the
> least significant hex digit when doing floating point comparisons.
>
> Regards,
> Scott Coutts

If I type the following:

>> a = 64.80000000000001;
>> b = 64.8;

what should I expect to see for the following expressions:

a > b
a == b

Neither the real quantity 64.80000000000001 nor the real quantity 64.8
is exactly representable in binary floating-point; the closest
representation for the first (in hex) is 4050333333333334 and the
closest representation for the second is 4050333333333333. They
differ by one bit. If MATLAB ignored that last bit, then "a > b"
would be false and "a == b" would be true. Wouldn't that be just as
confusing?

Another issue is that every individual floating-point arithmetic
operation is subject to similar round-off error, and that these errors
tend to accumulate. That means that it is impossible to choose a
single "equality threshold" that is appropriate for every person's
calculations. For example, the relative round-off error for an N-by-N
matrix multiply is (if I recall correctly) on the order of N*eps,
where eps is roughly 1e-16. This is because each element of the
result matrix is formed from a sequence of N multiplications and
additions.

I still maintain that this really isn't a language issue, or a
computer science versus engineering issue. The fact that a
floating-point arithmetic operation is an approximation subject to
round-off error is true whether you are using MATLAB, FORTRAN, C,
Java, Visual Basic, Microsoft Excel, or my beloved HP-15C engineering
calculator. The behavior we are talking about here can be
demonstrated in all of these environments.

There are other options. One could choose to do all integer
arithmetic, although that doesn't eliminate the worry of overflow.
One could use a symbolic math environment, such as Maple (or our
Symbolic Math Toolbox, which is based on Maple). Maple and the
Symbolic Math Toolbox also provide variable precision arithmetic,
which can reduce but never entirely eliminate the round-off error.
These options have their own disadvantages and are usually not
suitable for heavy-duty scientific and engineering number-crunching.

MATLAB uses floating point, and so it pays to keep in mind the
limitations of floating point.

Usually one uses a tolerance to test whether the results of
floating-point computations are "equal", as in

same = abs(a-b) < tol;

To go back to example that started this discussion, one might write:

idx = find(abs(z - .6*108) < 1e-8);

Regards,

Steve

Subject: strange FIND

From: Denis Gilbert

Date: 9 Jul, 1999 14:11:05

Message: 8 of 12

Steve,

Thanks for your instructive post explaining the consequences of roundoff
errors in equality tests. As Doug Schwarz pointed out, this issue comes
up relatively often in the newsgroup. I also find you responded in a
restrained manner to the rather rude "Hey, MATHWORKS?" line which ended one
of the above messages. Keep up the good work!

Denis Gilbert
gilbertd@XXXXYYZ.dfo-mpo.gc.ca (removing the XXXXYYZ)

Subject: Dead Horse

From: Nabeel

Date: 9 Jul, 1999 11:17:05

Message: 9 of 12

Michael Robbins wrote:
>
> Since equivalence testing is not reliable in MATLAB, is it possible
> for me to overload (if that's the right word) the == operator to use a
> tolerance?

Yup, you can overload it, but it's not really a good solution. In case
ou're interested, here's a quick example: Create a directory called
@double, make sure it's in a directory that's on your path, and include
a file like the following:

function y=eq(a,b)
y=(abs(a-b)<.1);

This checks for a and b being within .1 of each other. But you should
be aware that the comparison abs(a-b)<.1 is also being done in double
precision, so there may be roundoff errors there. Trying to correct
roundoff error with a method that's also prone to roundoff error can get
really tricky. So even with this method, you can still get a solution
that you don't want. There's no escaping it ;)

I personally suggest that you create a function called ISCLOSE and use
that to check numbers being close. This will be much less intrusive
than overlaoding ==. Plus, callig the function ISCLOSE rather than ==
is more descriptive of what you're really trying to do.

function y=isclose(a,b,tol)
y=(abs(a-b)<tol);

One more thing - some time ago Cleve wrote a really nice article about
round-off error. It's in the Fall 196 News and Notes issue, click on
this link to get to it:

 http://www.mathworks.com/company/newsletter/fall96toc.shtml

It makes for some nice reading.

hope you have a nice weekend,

Nabeel

Subject: strange FIND

From: Scott Coutts

Date: 10 Jul, 1999 10:53:23

Message: 10 of 12

Steve,

Thanks for your reply - I see that the accumulation of round-off errors may prohibit a
simple solution. As I said, this in an interesting problem. It reminds me of a great
old Macintosh advertisement I saw that depicted a very successful looking gentleman who
says "I want a computer that makes me better at what I do. And I don't do computers."
One of the benefits of high-level languages and operating systems is that it insulates
the user from the low-level details of the computer hardware. Yet here is a case where
a very low-level hardware detail is causing problems to users of a very high-level
computer language. If this problem is showing up weekly on this use group that
perhaps, if nothing else, Matlab needs to describe the pitfalls of using relational
operators with floating point numbers somewhere in their documentation. I checked
"relation operators" in the "Using Matlab" manual and there is no mention of it
although the examples cited use integers. (Which is a little ironic because integers
are represented internally as double-precision floating point numbers in Matlab, aren't
they?)

I started using Matlab in 1988 and have noticed an interesting trend over the past 10
years. In the pre-Matlab days, scientists and researches tended to be supported by
small teams of programmers. It was the job of the programmers to implement the ideas,
simulations, or algorithms provided by the scientists and researchers. When Matlab
first appeared the scientists used it to generate prototypes of algorithms, etc., and
then gave the Matlab scripts to the programmers to be written in a "real" scientific
language like Fortran. In many cases the Fortran programs ran 100 times faster than the
early Matlab scripts. Now, the hardware and software has evolved to the point where the
scientists and researches, in many cases, can do there own thing without the help of
programmers. Something very obvious to a programmer, like the fact that 64.8 is not
always equal to 64.8, is not necessarily obvious to the general scientific community.
If so, if wouldn't show up here every week.

-Scott




The fact that it shows up weekly on the use group suggests that perhaps Matlab needs

eddins@mathworks.com wrote:

> Scott Coutts <scoutts@ll.mit.edu> writes:
>
> > This is an interesting problem and I find your response to be a little
> > condescending.
>
> Rereading my original post, I see how it could be taken that way. I
> sincerely apologize, for I meant no slight.
>
> > The strength of Matlab is that it permits engineers and scientists
> > from fields _other than_computer_science_ to solve problems effectively. It
> > should not be compared to languages used mainly by software professionals. A
> > Matlab user should not be forced to understand the inner workings of the computer
> > to the level of detail you suggest. If my Matlab scripts asks if 64.8 is equal to
> > 64.8 then the result should be true, especially when the script is using only one
> > digit after the decimal point as in the original example. In the example you cite
> > 4050333333333334 is compared to 4050333333333333 with a false result. At first
> > glance, it would seem that a simple solution would be for Matlab to drop the
> > least significant hex digit when doing floating point comparisons.
> >
> > Regards,
> > Scott Coutts
>
> If I type the following:
>
> >> a = 64.80000000000001;
> >> b = 64.8;
>
> what should I expect to see for the following expressions:
>
> a > b
> a == b
>
> Neither the real quantity 64.80000000000001 nor the real quantity 64.8
> is exactly representable in binary floating-point; the closest
> representation for the first (in hex) is 4050333333333334 and the
> closest representation for the second is 4050333333333333. They
> differ by one bit. If MATLAB ignored that last bit, then "a > b"
> would be false and "a == b" would be true. Wouldn't that be just as
> confusing?
>
> Another issue is that every individual floating-point arithmetic
> operation is subject to similar round-off error, and that these errors
> tend to accumulate. That means that it is impossible to choose a
> single "equality threshold" that is appropriate for every person's
> calculations. For example, the relative round-off error for an N-by-N
> matrix multiply is (if I recall correctly) on the order of N*eps,
> where eps is roughly 1e-16. This is because each element of the
> result matrix is formed from a sequence of N multiplications and
> additions.
>
> I still maintain that this really isn't a language issue, or a
> computer science versus engineering issue. The fact that a
> floating-point arithmetic operation is an approximation subject to
> round-off error is true whether you are using MATLAB, FORTRAN, C,
> Java, Visual Basic, Microsoft Excel, or my beloved HP-15C engineering
> calculator. The behavior we are talking about here can be
> demonstrated in all of these environments.
>
> There are other options. One could choose to do all integer
> arithmetic, although that doesn't eliminate the worry of overflow.
> One could use a symbolic math environment, such as Maple (or our
> Symbolic Math Toolbox, which is based on Maple). Maple and the
> Symbolic Math Toolbox also provide variable precision arithmetic,
> which can reduce but never entirely eliminate the round-off error.
> These options have their own disadvantages and are usually not
> suitable for heavy-duty scientific and engineering number-crunching.
>
> MATLAB uses floating point, and so it pays to keep in mind the
> limitations of floating point.
>
> Usually one uses a tolerance to test whether the results of
> floating-point computations are "equal", as in
>
> same = abs(a-b) < tol;
>
> To go back to example that started this discussion, one might write:
>
> idx = find(abs(z - .6*108) < 1e-8);
>
> Regards,
>
> Steve

Subject: strange FIND

From: IPSIS

Date: 13 Jul, 1999 10:59:14

Message: 11 of 12

As a conclusion, I suggest that you simply replace:
> z=1:.1:300

with:
    z = 10:3000

and
> find(z==0.6*108)

with:
    find(z == 6*108)

As all numbers become integers, you'll get rid of your problem!

Hoping this helps...
Patrice HOUIZOT

________________________________________________________________
IPSIS - Ingenierie pour signaux et systemes

Phone: +33 2 99 27 53 27
Fax: +33 2 99 27 53 28
E-mail: automatique@ipsis.com
Web site: http://www.ipsis.com

Subject: strange FIND

From: Sam Sirlin

Date: 20 Jul, 1999 15:49:53

Message: 12 of 12

Scott Coutts <scoutts@ll.mit.edu> writes:

> Steve,
>
> Thanks for your reply - I see that the accumulation of round-off
> errors may prohibit a simple solution. As I said, this in an
> interesting problem.

Also an old and well known problem. The computer language APL used
relational operators with a built in comparison tolerance (or
fuzz). The fuzz defaulted to about 1e-13, which works well for most
computations. So many users need not address the issue specifically.
Of course anyone doing any numerical work ought to be aware of such
issues. It was user adjustable to some extent for special cases,
including 0 (no fuzz, same as more mundane languages).

(someone else wrote)
> > I still maintain that this really isn't a language issue, or a
> > computer science versus engineering issue. The fact that a
> > floating-point arithmetic operation is an approximation subject to
> > round-off error is true whether you are using MATLAB, FORTRAN, C,
> > Java, Visual Basic, Microsoft Excel, or my beloved HP-15C engineering
> > calculator. The behavior we are talking about here can be
> > demonstrated in all of these environments.

Certainly is a language issue, though of course fundamental to the
machines being used, considered long ago (60's!) by Iverson in
language design.

Some understanding and determination of computational fuzz is
necessary for most numerical work, for example even matlab has built
in eps, used for just this purpose, which I'm surprised never got
built into the language relational operators.

--
Sam Sirlin
Email: sam@kalessin.jpl.nasa.gov

Tags for this Thread

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

rssFeed for this Thread

Contact us at files@mathworks.com