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