Strange results for evaluating quadratic function on a linspace

2 visualizaciones (últimos 30 días)
Kai
Kai el 15 de Mayo de 2018
Editada: Kai el 15 de Mayo de 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!

Respuesta aceptada

John D'Errico
John D'Errico el 15 de Mayo de 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 comentario
Kai
Kai el 15 de Mayo de 2018
Editada: Kai el 15 de Mayo de 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.

Iniciar sesión para comentar.

Más respuestas (1)

Jan
Jan el 15 de Mayo de 2018
Editada: Jan el 15 de Mayo de 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

Categorías

Más información sobre Creating and Concatenating Matrices en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by