Strange results for evaluating quadratic function on a linspace

2 vues (au cours des 30 derniers jours)
Kai
Kai le 15 Mai 2018
Modifié(e) : Kai le 15 Mai 2018
Could it be that linspace is not working quite exactly?
Consider the following code:
X = linspace(-1.2,1.2,25);
F =@(x,y) x.^2+y.^2-1;
F(X(23),X(13))
It should be F(X(23),X(13)) = F(1,0) = 0, but somehow the result is
-4.440892098500626e-16
I came across this problem while trying to find intersections of an implicitly given curve and lattice knots (more precisely elements of ZxZ). A simple check such as
if F(X(i),X(j)) == 0
A = [A;X(i),X(j)];
end
should have sufficed, but apparently this is not working because of the above issue. I appreciate your help!
  1 commentaire
Kai
Kai le 15 Mai 2018
By the way, using the colon operator instead of linspace works well.

Connectez-vous pour commenter.

Réponse acceptée

John D'Errico
John D'Errico le 15 Mai 2018
Can you represent the number 1/3 EXACTLY as a decimal (thus base 10) number in a finite number of decimal digits? (Hint: NO)
Numbers in MATLAB (and in many such computational environments) are stored using double precision, using an IEEE standard form. That means they are stored with a 52 bit mantissa, stored as BINARY bits, thus effectively base 2. (If you prefer, 13 hexadecimal digits.)
Now, can you represent the number 1.2 EXACTLY in a finite number of binary bits? (Hint: read my first question again.)
Again, the answer is no. If you did try to represent 1.2 in binary, it would be an infinite repeating binary fraction, just like a repeating decimal approximation to 1/3 or 1/7.
1.00110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011
Thus 1 + 1/8 + 1/16 + 1/128 + 1/256 + ...
In fact, that gets us pretty close to 1.2.
1 + 1/8 + 1/16 + 1/128 + 1/256 ans = 1.1992
But not exactly so. And nothing you can do will represent 1.2 exactly in a finite binary form.
So this is not a linspace error. It is an error of understanding the limitations of floating point arithmetic.
  1 commentaire
Kai
Kai le 15 Mai 2018
Modifié(e) : Kai le 15 Mai 2018
Thank you! I was looking around a bit and yeah, I kinda forgot about this precision problem or I just never came across this issue with such simple numbers. I guess in this case I need to use something like
if abs(...) < 5*|eps|
(using factor 5 to be safe), right? I tried that and it works well now.

Connectez-vous pour commenter.

Plus de réponses (1)

Jan
Jan le 15 Mai 2018
Modifié(e) : Jan le 15 Mai 2018
Welcome to the world of numerics with limited precision. Remember that floating point numbers are displayed in decimal format, but store in binary format internally. This must lead to rounding effects and there is no way to avoid this. See also: FAQ: Why is 0.3-0.2~=0.1 .
4.44e-16 is 2*|eps|, which is the expected inaccuracy for the input data. linspace is working correctly.
Another standard example, where you see a 0 although a non-zero is expected mathematically:
1e17 + 1 - 1e17

Catégories

En savoir plus sur Creating and Concatenating Matrices dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by