-
1. Data: 2012-11-01 11:15:13
Temat: Błędny epsilon - this is not a bug, this is ?
Od: "slawek" <h...@s...pl>
Tzw. maszynowy epsilon (see Wikipedia) wynosi nie więcej niż 1.111E-016 dla
liczb 64-bitowych. Taki wynik łatwo otrzymać nawet naiwnym algorytmem, w
którym po kolei sprawdzane są w pętli kolejne wartości epsilon - każda
kolejna nieco (o ułamek procenta) mniejsza od poprzedniej. Algorytm "fast"
adaptacyjnie zmienia krok itd. - nie ma to znacznego wypływu na wynik, ale
liczba kroków jest znacznie mniejsza.
Jednak zaglądając do float.h w MS VS C++ można znaleźć definicję
DBL_EPSILON, wraz ze stosownym komentarzem, 2.22044604925031310000E-016.
Jest to niemal 2 razy więcej, niż naprawdę wynosi epsilon (obliczony właśnie
programem skompilowanym w MSVS C++). "This is not a bug, this is
inaccuracy" - chciałoby się powiedzieć.
Zaglądamy dalej - Matlab - tak ostatnio chwalony - ma wbudowaną funkcję
eps - zgadnijcie co zwraca eps jako wynik liczbowy? Tak, też się zdziwiłem -
przecież Matlab to Matlab.
Jeszcze raz rzut oka do Wikipedii - jest sobie wyraźnie dobra wartość
epsilona dla double w tabelce - ale już np. program w Phytonie i wyniki z
niego - znowu błędne 2.22E-16 . I nie jest to "wina Phytona" - ale po prostu
błąd w programie.
"Phytonowcy", staff MS i ludzie z MathWorks popełnili jeden i ten sam błąd -
dzielili przez dwa. Ciąg wartości x[n], jakie otrzymywali, dla dostatecznie
dużego n nie spełniał nierówności 1.0+x[n] > 1.0. Nie jest źle... jeżeli
pamięta się, że dokładność tak wyznaczonego epsilona wynosi plus minus 50%.
To nawet w większości praktycznych zastosowań wystarcza. Ale nie jest dobrym
pomysłem, by tak niedokładną wartość wrzucać jako wzorcową do float.h - bo
99.8% ludzi będzie w ciemno ufało w nieomylność MS - zwłaszcza, że podane
jest to jako, cyt.:
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that
1.0+DBL_EPSILON != 1.0 */
a to sugeruje poprawność wszystkich zapisanych cyfr znaczących. Tymczasem
eps znaleziony przez wykonywanie obliczeń (można oszacować epsilon przez
zapisane 1.0 oraz 1.0+epsilon bit po bicie mantysa i wykładnik - vide
IEEE753) leży gdzieś pomiędzy podanymi zakresami:
naive (no. of steps=36736783):
eps > 1.11022213668763790000E-016
eps <= 1.11022324691088480000E-016
fast (no. of steps=187):
eps > 1.11022302462515650000E-016
eps <= 1.11022302462515680000E-016
slawek
-
2. Data: 2012-11-01 12:08:13
Temat: Re: Błędny epsilon - this is not a bug, this is ?
Od: kenobi <p...@g...com>
W dniu czwartek, 1 listopada 2012 11:15:21 UTC+1 użytkownik slawek napisał:
> Tzw. maszynowy epsilon (see Wikipedia) wynosi nie więcej niż 1.111E-016 dla
>
> liczb 64-bitowych. Taki wynik łatwo otrzymać nawet naiwnym algorytmem, w
>
> którym po kolei sprawdzane są w pętli kolejne wartości epsilon - każda
>
> kolejna nieco (o ułamek procenta) mniejsza od poprzedniej. Algorytm "fast"
>
> adaptacyjnie zmienia krok itd. - nie ma to znacznego wypływu na wynik, ale
>
> liczba kroków jest znacznie mniejsza.
>
>
>
> Jednak zaglądając do float.h w MS VS C++ można znaleźć definicję
>
> DBL_EPSILON, wraz ze stosownym komentarzem, 2.22044604925031310000E-016.
>
> Jest to niemal 2 razy więcej, niż naprawdę wynosi epsilon (obliczony właśnie
>
> programem skompilowanym w MSVS C++). "This is not a bug, this is
>
> inaccuracy" - chciałoby się powiedzieć.
>
>
>
> Zaglądamy dalej - Matlab - tak ostatnio chwalony - ma wbudowaną funkcję
>
> eps - zgadnijcie co zwraca eps jako wynik liczbowy? Tak, też się zdziwiłem -
>
> przecież Matlab to Matlab.
>
>
>
> Jeszcze raz rzut oka do Wikipedii - jest sobie wyraźnie dobra wartość
>
> epsilona dla double w tabelce - ale już np. program w Phytonie i wyniki z
>
> niego - znowu błędne 2.22E-16 . I nie jest to "wina Phytona" - ale po prostu
>
> błąd w programie.
>
>
>
> "Phytonowcy", staff MS i ludzie z MathWorks popełnili jeden i ten sam błąd -
>
> dzielili przez dwa. Ciąg wartości x[n], jakie otrzymywali, dla dostatecznie
>
> dużego n nie spełniał nierówności 1.0+x[n] > 1.0. Nie jest źle... jeżeli
>
> pamięta się, że dokładność tak wyznaczonego epsilona wynosi plus minus 50%.
>
> To nawet w większości praktycznych zastosowań wystarcza. Ale nie jest dobrym
>
> pomysłem, by tak niedokładną wartość wrzucać jako wzorcową do float.h - bo
>
> 99.8% ludzi będzie w ciemno ufało w nieomylność MS - zwłaszcza, że podane
>
> jest to jako, cyt.:
>
>
>
> #define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that
>
> 1.0+DBL_EPSILON != 1.0 */
>
>
>
> a to sugeruje poprawność wszystkich zapisanych cyfr znaczących. Tymczasem
>
> eps znaleziony przez wykonywanie obliczeń (można oszacować epsilon przez
>
> zapisane 1.0 oraz 1.0+epsilon bit po bicie mantysa i wykładnik - vide
>
> IEEE753) leży gdzieś pomiędzy podanymi zakresami:
>
>
>
> naive (no. of steps=36736783):
>
> eps > 1.11022213668763790000E-016
>
> eps <= 1.11022324691088480000E-016
>
>
>
> fast (no. of steps=187):
>
> eps > 1.11022302462515650000E-016
>
> eps <= 1.11022302462515680000E-016
>
>
Ciekawe, ale dlaczego to jest dokladnie podwojona
wartosc epsilona? Z poczatku wydawalo mni sie ze slowo double odnosi sie wlasnie do
tego (a nie do typu double) i ze ta podwojna wartosc ma jakiej uzasadnienie
-
3. Data: 2012-11-01 13:38:50
Temat: Re: Błędny epsilon - this is not a bug, this is ?
Od: "slawek" <h...@s...pl>
Użytkownik "kenobi" napisał w wiadomości grup
dyskusyjnych:a6f13eb6-6410-40f4-bafc-010780c2c620@go
oglegroups.com...
>Ciekawe, ale dlaczego to jest dokladnie podwojona
>wartosc epsilona? Z poczatku wydawalo mni sie ze slowo double odnosi sie
>wlasnie do tego (a nie do typu double) i ze ta podwojna wartosc ma jakiej
>uzasadnienie
Jeżeli zapisać:
double x = 1.0;
while(1.0 + x > 1.0)
{
cout << (x * k) << endl; // gdzie 0.0 <= k && k < 1.0
}
to ostatnia liczba jaka się pojawia na ekranie jest mniejsza niż epsilon, a
przedostatnia jest większa niż epsilon.
Biorąc k = 0.5, czyli połowiąc - dostaniemy jako tę większą właśnie to co
wpisane jest we float.h i co zwraca Matlabowe eps.
Jednak - jak łatwo się przekonać, biorąc np. k = 0.9999, nie jest prawdą że
DBL_EPSILON z float.h jest naprawdę epsilonem w sensie definicji jaka jest w
komentarzu z float.h.
Po prostu ktoś gdzieś (i to przynajmniej 3 różnych ludzi, w zupełnie różnych
"firmach" - bo ci od Phytona to "sweterki") użył zbyt prostego algorytmu nie
zastanawiając się nad dokładnością, precyzją i takimi tam. Wyszło jak
wyszło - czyli z błędem około 50% (błąd względny w procentach wynosi około
(1-k)*100%). Jak policzyć 2.2E-16 +- 50% to wychodzi gdzieś od 1.1E-16 do
3.3E-16, czyli wszystko się zgadza. Ale bez sensu było wpisywanie w
DBL_EPSILON wszystkich cyferek - przy 50% dokładności to jedna cyfra znacząc
jest i tak za dużo.
Napisałem do MS - może poprawią (a może poprawili, nie chce mi się
instalować MSVS 2012, ale chyba zrobię to w najbliższej przyszłości - czytaj
za jakieś parę tygodni).
Do Matlab'owców - też a zwłaszcza - ale musiałbym jeszcze sprawdzić z
nowszym Matlab'em (zły eps jest z R2010b).
No i poprawić wpis w Wikipedii - fragment Phyton'owy.
Warto sprawdzić byłoby i z Octave/Scilab/.../GCC. Zajrzeć do normy IEEE (tam
powinno być dobrze, a może też sztucznie stworzyć eps przez rozrysowanie
bitów).
slawek
-
4. Data: 2012-11-01 14:49:57
Temat: Re: Błędny epsilon - this is not a bug, this is ?
Od: bartekltg <b...@g...com>
W dniu 2012-11-01 12:08, kenobi pisze:
>>
> Ciekawe, ale dlaczego to jest dokladnie podwojona
> wartosc epsilona? Z poczatku wydawalo mni sie ze slowo double odnosi sie wlasnie do
tego (a nie do typu double) i ze ta podwojna wartosc ma jakiej uzasadnienie
>
Z powodu niedoczytania i niejasnej definicji (definicja w floath.h
jest myląca, ale ta w eps w matalbie powinna wszystko wyjaśnić).
Bierzemy 1 i nasz epsylon_s = 1.11022324691088480000E-16.
Odpalamy:
ee=1.11022324691088480000E-16
a=1+ee
roznica = a-1
Wychodzi:
ee =
1.1102e-016
a =
1.0000
roznica =
2.2204e-016
Odległość między 1 a następną liczbą double wynosi 2.2204e-016,
i to jest prawdziwa dokładność maszynowa.
Dlaczego ten dwa razy mniejszy działa dla 'testu' 1+eps != 1?
Koprocesor Zaokrąglanie. Koprocesor działa na ciut dłuższych
liczbach niż 64bity (80bitów na x86) dodaje bez problemu 1 do
epsylona sławka, następnie rzutuje na double. A, że jest w połowie
drogi do następnej liczby zapisywalnej w double, zaokrągla w górę.
I różnica wychodzi 2.2204e-016.
Ale nie znajdziesz takiej liczby x>1, aby |x-1|= 1.1102e-016
Co bardziej zasługuje na nazwę epsylon maszynowy,
1+eps != 1 czy eps = min_{x>1} (x-1)
to dyskusja o wyższości świat przesilenia zimowego na marsie
i rocznicy uśpienia chutuchtu.
I tak używamy raczej liczb typu 100*eps, gdzie to 100 jest bardzo
orientacyjne czy, częściej i większą podbudową teoretyczną, np
sqrt(eps).
Jeśli nasz program 'działa' dla jednego z tych epsyllonów,
a nie "działa" dla drugiego, to i tak trzeba pomyśleć albo
użyć większej precyzji.
A, żeby było zabawniej:
ee=1.11022324691088480000E-16/2 %dwa razy mniej!
a=1-ee
roznica = a-1
ee =
5.5511e-017
a =
1.0000
roznica =
-1.1102e-016
:-)
pzdr
bartekltg
-
5. Data: 2012-11-01 14:53:27
Temat: Re: Błędny epsilon - this is not a bug, this is ?
Od: bartekltg <b...@g...com>
W dniu 2012-11-01 13:38, slawek pisze:
>
>
> Do Matlab'owców - też a zwłaszcza - ale musiałbym jeszcze sprawdzić z
> nowszym Matlab'em (zły eps jest z R2010b).
W matalbie jest poprawnie.
"
eps Spacing of floating point numbers.
D = eps(X), is the positive distance from ABS(X) to the next larger in
magnitude floating point number of the same precision as X.
"
I działa zgodnie z tą definicją.
eps(1) = 2.2204e-016
we float.h dali ciała z definicją/warunkami zaokrąglania.
Więcej pod postem fira.
pzdr
bartekltg
-
6. Data: 2012-11-01 16:39:09
Temat: Re: Błędny epsilon - this is not a bug, this is ?
Od: "slawek" <h...@s...pl>
Użytkownik "bartekltg" napisał w wiadomości grup
dyskusyjnych:k6tusp$elk$...@n...news.atman.pl...
>we float.h dali ciała z definicją/warunkami zaokrąglania.
Bartuś, gratuluję ci pewności siebie. Przyda ci się ona przy wyjaśnianiu
dlaczego twórcy procesorów dodają liczby z większą "rozdziałką" niż one są
zapisywane.
Owszem, opis we float.h jest niezbyt udany (m.i. dlatego, że w określeniu
"najmniejszą liczbą x która 1 + x != 1" zapomniano o liczbach ujemnych).
Nadal jednak masz problem - twierdzisz coś zupełnie innego niż Wikipedia -
więc może sprostujesz wpis ibidem? Przy okazji doprowadzając hasło do
porządku: ta sama Wikipedia podaje jako wartość epsilon - w tym samym
tekście - raz jako 1.1E-16 a raz jako 2.2E-16. Jako w miarę inteligentny
człowiek rozumiesz, że niezależnie od tego ile naprawdę wynosi epsilon
(nawet jeżeli jest to okrągłe 42) - to przynajmniej jedną z tych wartości
należy wykluczyć. (Nie, nie twierdzę że Wikipedia jest nieomylna - ale że
skoro potrafisz, to powinieneś sprostować błędy w Wikipiedii, nie będę
zabraniał.)
Co do Matlaba - jeżeli jest inna definicja - to eps z Matlaba jest ok - w
sensie zgodności z definicją. Niemniej jednak błędem jest w takim razie
odrzucanie liczb mniejszych niż eps (tj. niż wartość jaką zwraca funkcja eps
z Matlaba), bo te liczby jednak zmieniają (i powinny zmieniać) wynik. Taki
przykładzik, w którym f jest taka że dla każdego n funkcja f(n+1) < f(n)
oraz f(n) > 0 :
m = 1; while( f(m) >= eps ) m++; /* m = 10*m + 100; */ s = 0.; for (k =
m; k > 0; k--) s += f(m);
Jeżeli użyjesz definicji i wartości eps z Matlab, to możesz - przez
przypadek - otrzymać inny wynik, niż kiedy usuniesz komentarz. Jeżeli
użyjesz definicji MS (i oczywiście o połowę mniejszego eps) - to niezależnie
od tego, czy usuniesz komentarz, czy go zostawisz - będziesz miał ten sam
wynik.
Wniosek jest oczywisty - podana przez ciebie definicja może w określonych
sytuacjach prowadzić do błędnych wyników. Definicja MS jest bardziej
bezpieczna.
-
7. Data: 2012-11-01 16:54:26
Temat: Re: Błędny epsilon - this is not a bug, this is ?
Od: bartekltg <b...@g...com>
W dniu 2012-11-01 16:39, slawek pisze:
> Użytkownik "bartekltg" napisał w wiadomości grup
> dyskusyjnych:k6tusp$elk$...@n...news.atman.pl...
>
>> we float.h dali ciała z definicją/warunkami zaokrąglania.
>
> Bartuś, gratuluję ci pewności siebie. Przyda ci się ona przy wyjaśnianiu
> dlaczego twórcy procesorów dodają liczby z większą "rozdziałką" niż one
> są zapisywane.
Kurde, 'sławuś', wuemy, zę masz problemy z czytaniem ze zrozumieniem,
ale się skup i przeczytaj te posty.
> Nadal jednak masz problem - twierdzisz coś zupełnie innego niż Wikipedia
> - więc może sprostujesz wpis ibidem? Przy okazji doprowadzając hasło do
Gdzie twierdzę coś innego niż wykipedia?
Rozumiesz wynik tego:
Odpalamy:
ee=1.11022324691088480000E-16
a=1+ee
roznica = a-1
Wychodzi:
ee =
1.1102e-016
a =
1.0000
roznica =
2.2204e-016
I co tu więcej komentować.
>
> Co do Matlaba - jeżeli jest inna definicja - to eps z Matlaba jest ok -
> w sensie zgodności z definicją. Niemniej jednak błędem jest w takim
> razie odrzucanie liczb mniejszych niż eps (tj. niż wartość jaką zwraca
Błędem jest w ogóle działanie na takich zakresach.
To chyba podstawy 'numerków'.
> funkcja eps z Matlaba), bo te liczby jednak zmieniają (i powinny
> zmieniać) wynik. Taki przykładzik, w którym f jest taka że dla każdego n
> funkcja f(n+1) < f(n) oraz f(n) > 0 :
>
> m = 1; while( f(m) >= eps ) m++; /* m = 10*m + 100; */ s = 0.; for (k
> = m; k > 0; k--) s += f(m);
>
> Jeżeli użyjesz definicji i wartości eps z Matlab, to możesz - przez
> przypadek - otrzymać inny wynik, niż kiedy usuniesz komentarz. Jeżeli
> użyjesz definicji MS (i oczywiście o połowę mniejszego eps) - to
> niezależnie od tego, czy usuniesz komentarz, czy go zostawisz - będziesz
> miał ten sam wynik.
Będziesz miał syf. To nie sa integery, nie powinno się działać
na 'ostatnich bitach'.
Za ten kod powyżęj to powinni walić linijką po łapach.
> Wniosek jest oczywisty - podana przez ciebie definicja może w
> określonych sytuacjach prowadzić do błędnych wyników. Definicja MS jest
> bardziej bezpieczna.
Twoje pomysły na korzystanie z epsylona sa niebezpieczne.
pzdr
bardtekltg
-
8. Data: 2012-11-01 17:45:29
Temat: Re: Błędny epsilon - this is not a bug, this is ?
Od: "slawek" <h...@s...pl>
Użytkownik "bartekltg" napisał w wiadomości grup
dyskusyjnych:k6u5vk$cf9$...@n...news.atman.pl...
>Gdzie twierdzę coś innego niż wykipedia?
Zajrzyj do Wikipedii, przeczytaj. Umiesz czytać - więc w czym trudność?
>Błędem jest w ogóle działanie na takich zakresach.
>To chyba podstawy 'numerków'.
Stała Plancka ci zniknęła. Zniknęła ci stała Plancka do kwadratu podzielona
przez czwartą potęgą prędkości światła i pomnożona przez liczbę Avogadro.
Oczywiście... w CGS.
>Będziesz miał syf. To nie sa integery, nie powinno się działać
>na 'ostatnich bitach'.
Nie będę miał. Nie znam twoje siostry. Te zdania mają tyle ze sobą
wspólnego, co podany przykład z liczbami integer.
W podanym przykładzie liczenie jest "po wszystkich bitach" - bez
"zapominania" o dodawaniu wyrazów, które choć dość małe, to jednak wynik
zmieniają. Dla ciebie może to być bez znaczenia - ot, nauczyli cię że np.
sinus alfa to prawie to samo co alfa (dobrze jeżeli jeszcze zapamiętałeś, że
alfa ma być w radianach). W takim obrazie rzeczywistości (np. gry
komputerowe) epsilon jest do niczego nie potrzebny: jak coś będzie nieco
krzywo i niezbyt dokładnie, to i tak framerate ważniejsze jest.
>Za ten kod powyżęj to powinni walić linijką po łapach.
Jakieś doświadczenia z dzieciństwa?
Ale ja nie o tym. Tylko z uprzejmym pytaniem: jak TY
(o-wielki-i-wspaniały-Bartusiu) rozwiązałbyś prosty problem... masz szereg,
możesz sumować dowolną (acz skończoną) ilość wyrazów tegoż. Każdy wyraz
szeregu jest nieco mniejszy co do modułu od poprzedniego. Oczywiście, szereg
jest zbieżny. Chcesz szybko ocenić ile wyrazów trzeba będzie uwzględnić w
obliczeniach, tak aby zminimalizować błędy zaokrągleń. Wiesz - za długo
pisać "dlaczego" - że suma pominiętych wyrazów (tj. tzw. reszta) jest
mniejsza niż ostatni nie-pominięty składnik. Nie chcesz robić tego przy
sumowaniu "od 1 do m", bo wiesz że wtedy błędy zaokrągleń będą zbyt duże (a
przecież wiesz co to schemat Hornera). Gorzej - każdy z wyrazów zawiera
czynnik C[n], który jest "bardzo trudny do obliczenia" (np. całka w
przestrzeni 5-cio wymiarowej), ale szczęśliwie wiesz, że Abs[C[n]] < 1
niezależnie od n.
I teraz totalnie głupie pytanie: przyda się jakiś epsilon do tego? Jaki,
jak, bo? Podaj jakieś konstruktywne rozwiązanie - przyda się!
Bo to co na razie robisz, to wygląda na typową trollerkę o to kto był
najbardziej bity linijką po łapach. (W tym niestety przegrywam - nikt nie
chce mnie w moim przedszkolu bić linijką - może to się zmieni, gdy zacznę
chodzić do podstawówki w mieście w którym dorastałeś - gdzie to było?)
Na serio poczytaj co pisze w Wikipedii:
http://en.wikipedia.org/wiki/Machine_epsilon - tabelka z niby IEEE-754 - jak
wół stoi 1.11e-16 i nawet obok pow(2,-53) jest
-
9. Data: 2012-11-01 17:50:36
Temat: Re: Błędny epsilon - this is not a bug, this is ?
Od: bartekltg <b...@g...com>
W dniu 2012-11-01 17:45, slawek pisze:
> Użytkownik "bartekltg" napisał w wiadomości grup
> dyskusyjnych:k6u5vk$cf9$...@n...news.atman.pl...
>
>> Będziesz miał syf. To nie sa integery, nie powinno się działać
>> na 'ostatnich bitach'.
>
> Nie będę miał. Nie znam twoje siostry.
>
Twoje ogólne dyletanctwo można tolerować. To, że mimo
usilnych prób nie byłeś w stanie przez tydzień pojąć
działania kwadratur numerycznych czy FFT mogę zrozumieć.
To, że nie rozumies,z jak używać liczb zmiennoprzecinkowych,
też. Nie każdy musi.
Ale chamstwa tolerować nie będę.
plonk
-
10. Data: 2012-11-01 18:18:51
Temat: Re: Błędny epsilon - this is not a bug, this is ?
Od: "slawek" <h...@s...pl>
Użytkownik "bartekltg" napisał w wiadomości grup
dyskusyjnych:k6u98u$fjc$...@n...news.atman.pl...
>To, że nie rozumies,z jak używać liczb zmiennoprzecinkowych,
>też. Nie każdy musi.
Sam jesteś tego najlepszym przykładem: gdy zapytać się ciebie o konkret i
poprosić o konstruktywne wyjaśnienie - udajesz obrażoną pensjonarkę. Swoją
drogą, jakoś tak nie widziałem (ale pewnie nie pamiętam lub nie zauważyłem)
abyś kiedykolwiek podał jakiś sensowny sposób rozwiązania jakiegokolwiek
problemu. Dobry jesteś tylko w FUD i PR, reszta to jakaś taka mglista.
>Ale chamstwa tolerować nie będę.
Źle cię oceniłem - myślałem "weźmie się Bartuś ujmie ambicją i honorem... i
hasło w Wikipedii poprawi... będzie pożytek dla Ludzkości". Ale widzę że
ambicji bardzo dużo, wiedzy trochę mało, pracowitości nic a nic, co do
honoru... nawet nie ma o czym pisać.
Teraz widzę że już pożytku z pana hrabiego (galicyjskiego) nie będzie.