Why Is Colon Operator Not Equivalent To linspace Command?
35 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Why does q not equal zero in the following?
q = isequal(0:.08:50000,linspace(0,50000,625001))
1 Commento
Voss
il 14 Nov 2024 alle 20:21
A = 0:0.08:50000;
B = linspace(0,50000,625001);
C = (0:50000*12.5)/12.5;
isequal(A,B)
isequal(A,C)
isequal(B,C)
Risposte (3)
James Tursa
il 14 Nov 2024 alle 18:00
Modificato: James Tursa
il 14 Nov 2024 alle 18:12
The short answer is that the algorithms are different. In the first place, 0.08 cannot be represented exactly in IEEE double precision floating point, so using that as the delta does result in some binary floating point calculation inaccuracies compared to what you might expect looking at the decimal version. E.g., if you read the doc for colon, it doesn't even guarantee that you get the requested end point if the delta is not an integer. On the other hand, the linspace algorithm always gives you the end points. Also, the intermediate points might not match up exactly either, again because of floating point effects based on the different algorithms. E.g.,
a = 0:.08:50000;
b = linspace(0,50000,625001);
numel(a) == numel(b)
max(abs(a-b))
In your case, you happened to get the same number of elements with both methods, but the points generated are not exactly the same because of floating point effects of the different algorithms.
k = find(a ~= b,1,'last')
eps(a(k))
num2hex(a(k))
num2hex(b(k))
And above you can see the max difference is on the order of eps of the largest element that had a difference. I.e., the very last bit of the floating point value. Generally I would prefer linspace over colon in cases like yours so that you have control over the end points being generated.
0 Commenti
Torsten
il 14 Nov 2024 alle 18:04
Both arrays seem to be generated differently such that floating point issues come into play:
z1 = 0:.08:50000;
z2 = linspace(0,50000,625001);
[~,idx] = find(z1~=z2);
format long
z1(idx)-z2(idx)
0 Commenti
Walter Roberson
il 14 Nov 2024 alle 22:04
The colon operator is defined to use repeated addition. When the increment does not happen to be an integer multiple of a power of 2, there are round-off error problems. For example, 0.08 is not represented by the rational fraction 8 / 100
fprintf('%.999g\n', 0.08)
those ....1665<etc> accumulate under repeated addition.
The colon operator is not defined as (0:NumberOfValues-1)*Increment+BaseNumber . If it were defined that way, then
for K = 1:inf
would have to generate a vector 1, 2, 3, ... 9223372036854775806 ahead of time and use the elements from that vector. But 9223372036854775806 is 2^63 and it is not possible to generate vectors longer than 2^47-1 even if memory was available.
Of course, potentially MATLAB could have defined that the colon operator in
K=1:1.1:2^40
worked differently than the colon operator in
for K=1:1.1:2^40
but it chose to define them the same way: using repeated addition both ways.
0 Commenti
Vedere anche
Categorie
Scopri di più su Logical in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!