フィルターのクリア

Strange results for evaluating quadratic function on a linspace

1 回表示 (過去 30 日間)
Kai
Kai 2018 年 5 月 15 日
編集済み: Kai 2018 年 5 月 15 日
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 件のコメント
Kai
Kai 2018 年 5 月 15 日
By the way, using the colon operator instead of linspace works well.

サインインしてコメントする。

採用された回答

John D'Errico
John D'Errico 2018 年 5 月 15 日
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 件のコメント
Kai
Kai 2018 年 5 月 15 日
編集済み: Kai 2018 年 5 月 15 日
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.

サインインしてコメントする。

その他の回答 (1 件)

Jan
Jan 2018 年 5 月 15 日
編集済み: Jan 2018 年 5 月 15 日
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

カテゴリ

Help Center および File ExchangeCreating and Concatenating Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by