Zaloguj się
Blog na Matlablog
Forum polskich użytkowników
 
UŻYTKOWNICY GRUPY PROFIL Zaloguj się, by sprawdzić wiadomości FAQ
 



Napisz nowy temat     Odpowiedz do tematu Zobacz poprzedni temat :: Zobacz następny temat

dokładność numeryczna
Forum MATLAB Strona Główna-> MATLAB
Post Wysłany: 31 Maj 2009, Nie 10:00 pm Temat postu: dokładność numeryczna Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
dziś spotkałem się z takim problemem. Wykonując ten kod:
Kod:

for k=.1:.1:5
    
if k == round(k)
  
disp(k)
    
end
end

dostaję 1 2 4 5
Kiedy zrobię tak:
Kod:

k
=.1:.1:5;
for
m=1:length(k)
    if
k(m) == round(k(m))
  
disp(k(m))
    
end
end

Otrzymuję spodziewany wynik 1 2 3 4 5
Czy ktoś ma pomysł dlaczego tak się dzieje?
A może to tylko na 64 bitowym linuxie? Bo na takim systemie mam matlaba.


 

Post Wysłany: 1 Czerwca 2009, Pon 9:34 am Temat postu: Odpowiedz z cytatem
 
AUTOR:
Vieniava
Może pisać książki


Dołączył: 13 Cze 2006
Posty: 445
Skąd: Warszawa


Ogląda profil użytkownika Wyślij prywatną wiadomość Wyślij email Odwiedź stronę autora
O kurcze!
U mnie to samo.
Kod:
for k=0.2:0.1:5
    
if k == round(k)
  
disp(k)
    
end
end

daje: 1 2 4
Kod:
for k=0.3:0.1:5
    
if k == round(k)
  
disp(k)
    
end
end

daje: 1 2 3 4 5

Trzeba to zgłosić do MathWorksa
 

Post Wysłany: 1 Czerwca 2009, Pon 9:37 am Temat postu: Odpowiedz z cytatem
 
AUTOR:
Vieniava
Może pisać książki


Dołączył: 13 Cze 2006
Posty: 445
Skąd: Warszawa


Ogląda profil użytkownika Wyślij prywatną wiadomość Wyślij email Odwiedź stronę autora
jest tu jakiś błąd podczas generowania wektora dla petli for.
Z kolei:
Kod:

for k=[0.1:0.1:5]
    if
k == round(k)
        
disp(k)
    
end
end

działa poprawnie !!!

PS na ktorym Matlabie działasz (polecenie ver)
 

Post Wysłany: 1 Czerwca 2009, Pon 10:43 am Temat postu: Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
właśnie sprawdziłem to na testowej wersji najnowszego matlaba:

MATLAB Version 7.8.0.347 (R2009a)


i też działa tak jak napisałem wcześniej.


 

Post Wysłany: 1 Czerwca 2009, Pon 1:05 pm Temat postu: Odpowiedz z cytatem
 
AUTOR:
mpi
Site Admin


Dołączył: 11 Gru 2005
Posty: 272
Skąd: Kraków


Ogląda profil użytkownika Wyślij prywatną wiadomość Wyślij email Odwiedź stronę autora
To nie jest błąd Matlaba tylko problem z reprezentacją liczb zmiennoprzecinkowych. Wszystko wynika z tego, że tablice iterowane (tzn. k = 0.1:0.1:5) są tworzone poprzez dodawanie kroku (tutaj 0.1) do poprzedniego wyniku co powoduje nacałkowanie błędu. Z tego powodu na samym końcu zamiast 5 k jest równe jakieś 5.00000000000000001 lub podobnie.

Dyskutowałem na ten temat już wielokrotnie z supportem Matlaba i niestety nie są w stanie tego w żaden poprawić, bo ogranicza ich dokładność maszyny (tzn. procesora). Stworzyli nawet taką stronę o reprezentacji zmiennoprzecinkowej (http://www.mathworks.com/support/tech-notes/1100/1108.html), warto poczytać.

Jedyne co mogę doradzić to nie używać zbyt długich tablic iterowanych to innych celów niż krokowanie pętli, a wszelkie operacje typu mod czy round są już zabójcze, chyba że dla krótkich tablic (najlepiej przetestować sobie wcześniej Command Line czy zadziała).


 

Post Wysłany: 1 Czerwca 2009, Pon 1:33 pm Temat postu: Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
Ok, ale dlaczego jest różnica pomiędzy tablicą definiowaną przed pętla i tablicą do krokowania pętli?

Kod:

k
=.1:.1:5;
m=1;
for
k1=.1:.1:5;
  
wynik(m) = k(m)-k1 ;
  
m = m +1;
end
plot
(wynik)


 

Post Wysłany: 1 Czerwca 2009, Pon 9:02 pm Temat postu: Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
Dodam, że w oktave kody z mojego pierwszego posta dają dwukrotnie ten sam wynik: 2 4 5, czyli wektory są identyczne.


 

Post Wysłany: 3 Czerwca 2009, Sro 2:27 pm Temat postu: Odpowiedz z cytatem
 
AUTOR:
mpi
Site Admin


Dołączył: 11 Gru 2005
Posty: 272
Skąd: Kraków


Ogląda profil użytkownika Wyślij prywatną wiadomość Wyślij email Odwiedź stronę autora
mc2 napisał:
Ok, ale dlaczego jest różnica pomiędzy tablicą definiowaną przed pętla i tablicą do krokowania pętli?

Kod:

k
=.1:.1:5;
m=1;
for
k1=.1:.1:5;
  
wynik(m) = k(m)-k1 ;
  
m = m +1;
end
plot
(wynik)

Trochę mi to zajęło, ale udało mi się dowiedzieć skąd się bierze różnica.

Wektor k jest tworzony i liczony przez BLAS (część jądra obliczeniowego Matlaba), który trzyma ją w 80 bitowych specjalnych rejestrach, żeby było dokładniej.

Wektor k1 jest tylko iteratorem pętli, więc ze względu na oszczędność pamięci jest tworzony i liczony w zwykłej zmiennej więc jest mniej dokładny.

Pamiętajcie, że producent NIE zaleca stosowania pętli for ze względu na tzw. małą elastyczność. Taką pętlę bardzo cieżko zoptymalizować, w przeciwieństwie do operacji wektorowych. Z operacjami wekotrowymi JIT potrafi wyprawiać prawdziwe cuda. Pętlę for uważa się za zło konieczne, a już nigdy, przenigdy nie powinno się wkładać precyzyjnych operacji matematycznych do iteratora.


 

Post Wysłany: 3 Czerwca 2009, Sro 5:26 pm Temat postu: Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
Dziękuję za wyczerpującą odpowiedź Smile


 

Post Wysłany: 11 Kwietnia 2010, Nie 7:47 pm Temat postu: Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
Przykład do czego może prowadzić niedokładność numeryczna:
http://mathworld.wolfram.com/RoundoffError.html
 

Post Wysłany: 20 Kwietnia 2011, Sro 11:36 am Temat postu: Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
Trafiłem na ciekawy przykład błędów wynikających z zaokrąglania (round-off error). Weźmy wielomian postaci:

Oczywiste jest, że jego 7-krotnym miejscem zerowym jest 1. Ale używając matlaba do odnalezienia pierwiatków otrzymamy nieco zaskakujący wynik:
Kod:
p = poly([1 1 1 1 1 1 1])
p =
    
1    -7    21   -35    35   -21     7    -1
r
= roots(p)
r =
  
1.0090         
   1.0056
+ 0.0070i
   1.0056
- 0.0070i
   0.9980
+ 0.0088i
   0.9980
- 0.0088i
   0.9919
+ 0.0039i
   0.9919
- 0.0039i


Rysując rozwiązanie w przestrzeni zespolonej widać, że są to bardzo zbliżone wartości:
Kod:
compass(r)

Ale sprawdzając nasze rozwiązanie widać, że odbiega ono od prawdziwej wartości (1):
Kod:
f1 = @(x)(x-1).^7;

f2 = @(x)x-7*x.^2+ 21*x.^3-35*x.^4+35*x.^5-21*x.^6+ 7*x.^7-1;

f1(r)
ans =
  
1.0e-14 *
  
0.4696         
   0.4749
- 0.0102i
   0.4749
+ 0.0102i
   0.4858
- 0.0120i
   0.4858
+ 0.0120i
   0.4936
- 0.0051i
   0.4936
+ 0.0051i

f2
(r)
ans =
  
0.0741         
   0.0445
+ 0.0583i
   0.0445
- 0.0583i
 
-0.0178 + 0.0694i
 
-0.0178 - 0.0694i
 
-0.0637 + 0.0297i
 
-0.0637 - 0.0297i

f1
(r)-f2(r)
ans =
  -
0.0741         
 
-0.0445 - 0.0583i
 
-0.0445 + 0.0583i
   0.0178
- 0.0694i
   0.0178
+ 0.0694i
   0.0637
- 0.0297i
   0.0637
+ 0.0297i


Także trzeba uważać Smile
 

Post Wysłany: 21 Października 2015, Sro 9:11 pm Temat postu: Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
mpi napisał:
mc2 napisał:
Ok, ale dlaczego jest różnica pomiędzy tablicą definiowaną przed pętla i tablicą do krokowania pętli?

Kod:

k
=.1:.1:5;
m=1;
for
k1=.1:.1:5;
  
wynik(m) = k(m)-k1 ;
  
m = m +1;
end
plot
(wynik)

Trochę mi to zajęło, ale udało mi się dowiedzieć skąd się bierze różnica.

Wektor k jest tworzony i liczony przez BLAS (część jądra obliczeniowego Matlaba), który trzyma ją w 80 bitowych specjalnych rejestrach, żeby było dokładniej.

Wektor k1 jest tylko iteratorem pętli, więc ze względu na oszczędność pamięci jest tworzony i liczony w zwykłej zmiennej więc jest mniej dokładny.

Pamiętajcie, że producent NIE zaleca stosowania pętli for ze względu na tzw. małą elastyczność. Taką pętlę bardzo cieżko zoptymalizować, w przeciwieństwie do operacji wektorowych. Z operacjami wekotrowymi JIT potrafi wyprawiać prawdziwe cuda. Pętlę for uważa się za zło konieczne, a już nigdy, przenigdy nie powinno się wkładać precyzyjnych operacji matematycznych do iteratora.


Odgrzewam kotleta, ale ostatnio natknąłem się na dość osobliwy problem w starej wersji MATLABa - 2010. Mianowicie wynik obliczeń różnił się w zależności od tego czy funkcja była wywołana zwyczajnie, czy w trybie debuggera (z kropką do zatrzymania się w wybranej linijce). W wersji 2015 wyniki były identyczne w obu przypadkach. Czy to możliwe, że w trybie debuggera MATLAB używał w przeszłości mniejszej precyzji niż w zwykłym trybie?
Funkcja była typu:
Kod:
function out = foo(a,b)
out = a < b;
 

Post Wysłany: 27 Października 2015, Wto 11:10 pm Temat postu: Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
mc2 napisał:
Czy to możliwe, że w trybie debuggera MATLAB używał w przeszłości mniejszej precyzji niż w zwykłym trybie?

Według Didiera Trosseta tak:
http://stackoverflow.com/questions/11151609/precision-differences-in-matlab-and-c?answertab=votes#tab-top
Didier Trosset napisał:
There is one thing in x86 CPU about floating points numbers. Internally, the floating point unit uses registers that are 10 bytes, i.e. 80 bits. Furthermore, the CPU has a setting that tells whether the floating point calculations should be made with 32 bits (float), 64 bits (double) or 80 bits precision. Less precision meaning faster executed floating point operations. (The 32 bits mode used to be popular for video games, where speed takes over precision).

From this I remember I tracked a bug in a calculation library (dll) that given the same input did not gave the same result whether it was started from a test C++ executable, or from MatLab.. Furthermore, this did not happen in Debug mode, only in Release!

The final conclusion was that MatLab did set the CPU floating point precision to 80 bits, whereas our test executable did not (and leave the default 64 bits precision). Furthermore, this calculation mismatch did not happen Debug mode because all the variables were written to memory into 64 bits double variables, and reloaded from there afterward, nullifying the additional 16 bits. In Release mode, some variables were optimized out (not written to memory), and all calculations were done with floating point registers only, on 80 bits, keeping the additional 16 bits non-zero value.
 

Post Wysłany: 23 Sierpnia 2017, Sro 7:59 pm Temat postu: Odpowiedz z cytatem
 
AUTOR:
mc2
Może pisać książki


Dołączył: 19 Maj 2009
Posty: 2234


Ogląda profil użytkownika Wyślij prywatną wiadomość Odwiedź stronę autora
Ostatnio podsumowałem ten wątek we wpisie na Matlablogu:
http://matlablog.ont.com.pl/dokladnosc-numeryczna/
 

Forum MATLAB Strona Główna-> MATLAB
Wyświetl posty z ostatnich:   

Napisz nowy temat     Odpowiedz do tematu Zobacz poprzedni temat :: Zobacz następny temat

Wszystkie czasy w strefie CET (Europa)

Skocz do:  

Statystyki forum:



Od dnia 08.06.2006 forum odwiedzano 39272836
Najwięcej użytkowników 266 było obecnych 19 Lutego 2015, Czw 7:03 pm

Aktualnie online:




Najnowsze posty na forum:
[S03E10] Outlander CDA Sezon 3 Odcinek 10 Online Zalukaj PL  (18 Listopada 2017, Sob 11:01 pm)
KrĂłlowe Ĺźycia 3 Sezon 12 Odcinek Online CDA (s03e12)  (18 Listopada 2017, Sob 5:36 pm)
KrĂłlowe Ĺźycia 3 Sezon 11 Odcinek Online CDA (s03e11)  (18 Listopada 2017, Sob 5:31 pm)
Rolnik szuka Ĺźony 4 Sezon 12 Odcinek Online CDA (s04e12)  (18 Listopada 2017, Sob 5:24 pm)
Złomowisko PL 5 Sezon 13 Odcinek Online CDA (s05e13)  (18 Listopada 2017, Sob 5:17 pm)
Na dobre i na złe 687 odcinek online - cda  (18 Listopada 2017, Sob 5:09 pm)
Na dobre i na złe 686 odcinek online - cda  (18 Listopada 2017, Sob 5:04 pm)
Rodzinka.pl 222 odcinek online - cda  (18 Listopada 2017, Sob 4:57 pm)
Rodzinka.pl 221 odcinek online - cda  (18 Listopada 2017, Sob 4:54 pm)
M jak Miłość 1332 odcinek online - cda  (18 Listopada 2017, Sob 4:48 pm)
Twoje prawa:
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Nie możesz ściągać plików na tym forum