Gauss, zajęcia 3. Pętle c.d. Przypomnijmy sobie jak działa pętla for Możemy podać normalnie w Gaussie v=zeros(1,10); for i(1,10,1); v[i]=i; endfor; print v; UWAGA: Lepiej jest taką operację wykonać przy pomocy jakieś opcje seqa. Trwa to zdecydowanie szybciej. Jeszcze jeden przykład metoda eliminacji Gaussa dla macierzy 3 na 3 /*Eliminacja w pierwszej kolumnie*/ for j(2,3,1); B[j,.]=B[j,.]-B[1,.]*B[j,1]/B[1,1]; endfor; /*Eliminacja w drugiej kolumnie*/ B[3,.]=B[3,.]-B[2,.]*B[3,2]/B[2,2]; print B; Pętla While Pętla while jest wykonywana tak długo jak spełniony jest jakiś warunek. Jest ona przydatna szczególnie wtedy, kiedy nie wiemy jak długo będziemy wykonywać jakąś pętle. Popatrzmy na przykład obliczeniowy Mamy macierz 1 1 1 1 e 0 0 0 A = 0 e 0 0 0 0 e 0 0 0 0 e 1
Jeśli e=0, to macierz ma liniowo zależne kolumny i wtedy A A jest macierzą osobliwą. Jeśli e jest różne od zera macierz A A jest odwracalna, gdyż A ma liniowo niezależne kolumny. Przy obliczeniach numerycznych komputer dla małych e będzie zaokrąglał obliczenia tak mocno, że A A okaże się macierzą osobliwą. Pytanie: dla jak małego e da się jeszcze obliczyć inv(a A)? Odp. Pętelka while eps=1.0; /* deklarowanie eps początkowego*/ do while eps > 1.0e-20; /* początek pętli - wykonuj do momentu, aż e < 1.0e-20 */ A = ones(1,4) (eps*eye(4)); print eps det(a'*a); eps=eps/10; endo; Można przejrzeć wyniki iż zobaczymy, że dla eps=1.0000e-008 wyznacznik już jest równy zero. Można jeszcze sprytniej. Tym razem skorzystamy z funkcji do until. Program jest wykonywany tak długo, aż po raz pierwszy zostanie spełniony warunek. eps=1.0; /* deklarowanie eps początkowego*/ do until eps < 1.0e-20; /* początek pętli - wykonuj do momentu, aż e < 1.0e-20 */ A = ones(1,4) (eps*eye(4)); if det(a'*a)==0; print eps; break; endif; eps=eps/10; endo; Proszę szczególnie zwrócić uwagę na linie z break. Używamy tu opcji break, która kończy wykonanie pętli do. Tak samo opcją break można kończyć pętle for. W przypadku zagnieżdżonych pętli (pętli w pętli) break kończy tylko swoją pętle. W zadaniach proszę Państwa o zrobienie ciekawszej opcji while dla tego przykładu. Tutaj tak naprawdę korzystamy z opcji typu for. Możemy przerywać w zależności od wyznacznika. Wczytywanie danych W pracy ekonomisty zazwyczaj korzystamy z zewnętrznych zbiorów danych. Niestety wczytywanie danych do Gaussa bywa dość uciążliwe. Gauss wczytuje tylko dane kodowane w ASCII. Czyli nie wczytuje np. danych z Excela. Jeżeli chcemy wczytać dane z Excela musimy zapisać je najpierw jako.csv, albo inny sposób rozdzielony przecinkiem, tabem, etc. Najlepiej jest równie usnąć wszystkie dane nienumeryczne. My mamy dodatkowe ograniczenie wynikające z Gauss light (maksymalnie 10.000 obserwacji) 2
load y[] = wig20.txt; Albo load y[] = c:\dane\wig20.txt; Przy tych opcjach wszystkie dane zostają wpisane w jedną długą kolumnę. Możemy je teraz przekształcić /*Ile wierszy mamy?*/ rows(y); /*Wiemy, że mamy 7 kolumn. Ile było oryginalnie wierszy?*/ rows(y)/7; k=reshape(y,51,7); /*Możemy oczywiście kilka operacji na raz wykonać*/ k2=reshape(y,rows(y)/7,7); Jeśli znamy z góry liczbę wierszy i kolumn możemy użyć tych opcji przy wczytywaniu load y2[ 51,7 ] = wig20.txt; y2; Podstawy statystyki w Gaussie W Matlabie mamy wbudowaną większość podstawowych statystyk Popatrzmy na kilka podstawowych dotyczących np. zmiennej close cl=y2[.,6]; /*średnia*/ meanc(cl) /*odchylenie standardowe*/ stdc(cl); Jeśli chcemy obliczyć wariancję w próbie, to musimy podnieść odchylenie standardowe do kwadratu /*wariancja*/ var=stdc(cl)^2; print var 3
Inne podstawowe statystyki opisowe skośność, kurtoza, kwantyle skew = kurt = N 3 ( i ) / i= 1 3 x x N ˆ σ N 4 ( i ) / i= 1 4 x x N ˆ σ Skośność ani kurtoza nie są standardowo oprogramowane w Gaussie. Jeśli chcemy z nich skorzystać musimy sami napisać swoją własną procedurę. /*Obliczenie skośności zadanego wektora*/ proc (1)=skewn(v); local h,n; n=rows(v); h=sumc((v-ones(n,1)* meanc(v))^3)/n/stdc(v)^3; /*Wzór na skośność*/ retp(h); /*Zwrócenie obliczeń*/ endp; Kolejną ważną statystyką używaną do badania rozkładu zmiennej są kwantyle. Jak wiemy kwantyl rzędu p zmiennej losowej X to taka liczba k, że P(X<k)=p Np. median to kwantyl rzędu 0.5, czyli taka liczba med., że P(X<med)=0.5 Nie znając rozkładu możemy estymować kwantyle używając kwantyli empirycznych. Policzymy kwantyle dla dziennych stóp zwrotu. Dzienne stopy zwrotu obliczymy jako różnicę logarytmów pomiędzy dwoma dniami. Na początek kilka prostych obliczeń. n=rows(cl); %stworzenie zmiennej dlclo=zeros(n,1); %uzupełnienie jej liczbami /*Pętla for w jednym wierszu*/ for i(2,n,1); dlclo[i]=log(cl[i])-log(cl[i-1]); endfor; Żeby obliczyć kwantyle empiryczne najłatwiej jest najpierw posortować dane 4
sr=sortc(dlclo,1); /*Pierwszy kwantyl*/ q25=sr[floor(0.25*n)]; q25; %Wartość znajdującą się w ¼ obserwacji %3 kwartyl q75=sr[floor(0.75*n)]; q75; Widzimy, że odległość między kwartylowa wynosi [-0.0027210903; 0.0025254767]. Zmienne pseudolosowe Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin. John von Neumann 1951. W wielu zastosowaniach używamy liczb pseudolosowych Liczby pseudolosowe są to z góry ustalone ciągi liczbowe, które bardzo dobrze imitują ciągi liczb losowych. Jako przykład weźmy ciąg liczb 13, 21, 57, 69, 73. Jaka będzie następna liczba? ni+1=17ni(mod 100) Modulo to reszta z dzielenia przez liczbę, np. 21(mod 4)=1 Odpowiednio dobierając punkt startowy oraz modulo możemy wygenerować liczby, które dość dobrze imitują liczby losowe na przedziale (0, max). Dzieląc przez max uzyskujemy rozkład jednostajny na odcinku [0,1]. W Gaussie jest to udoskonalony generator u = i 1 ( au + + i c)(mod m ) Mając rozkład jednostajny możemy uzyskać już wszystkie inne np. poprzez odwrotność dystrybuanty. Jak losujemy /*Zmienne z rozkładu standardowego normalnego*/ 5
R=rndn(10,10); R; /*Zmienne z rozkładu jednostajnego*/ R2=rndu(10,10); R2; Jeśli chcemy mieć zmienne z rozkładu niestandardowego musimy zastosować proste przekształcenia Jak wiemy X ~ N(0,1) X + a~ N( a,1) 2 b* X ~ N(0, b ) Wygenerujmy zmienną z rozkładu N(10,25). R3=10+5*rndn(100,1); /*Czy liczby mniej-więcej się zgadzają?*/ meanc(r3); stdc(r3); Nigdy nie uzyskamy idealnego dopasowania. Jeśli chcemy mieć zmienne z rozkładu jednostajnego, też stosujemy znane przekształcenia. Np. jeśli chcemy mieć zmienne z rozkładu U[1,5] R4=1+4*rndu(100,1); /*Sprawdźmy wartość najmniejszą i największą*/ maxc(r4); minc(r4); Przy generowaniu liczb pseudolosowych jedną z ważniejszych rzeczy jest ustalanie ziarna losowania czyli punktu startowego. Jak już wiemy liczby pseudolosowe są jednoznacznie wyznaczone i zadanie punktu startowego wyznacza nam cały wektor zmiennych. Ustalenie ziarna jest ważne, gdyż dzięki temu możemy nasze eksperymenty, czy obliczenia powtarzać. Każdego dnia, na każdym komputerze dostaniemy dokładnie ten sam wynik. W Gaussie możemy sterować też pozostałymi parametrami obliczeń rndmod ustala wartość m (modulo). Początkowo m = 2^31-1. rndmult ustala wartość a (mnożnika). Początkowo a= 397204094. rndseed ustala ziarno losowania (punkt startowy) 6
rndseed 3; r4=rndn(1,1); r4; Wylosuj jeszcze raz r4, a następnie znowu ustal rndseed na 3 i jeszcze raz wylosuj r4. W praktyce rndseed powinno być parzystą liczbą ok. 6 cyfrową. rndseed 323232; Inne rozkłady oprogramowane w Gaussie Rozkład Poissona k e λ λ PX ( = k) =, k= 0,1,2, k! X=rndp(100,1,5); /*Wektor zmiennych losowych o rozkładzie Poissona z parametrem lambda*/ Rozkład gamma α β f ( x) = x Γ ( α) α 1 e β x X=rndgam(1000,1,7); Tylko dla beta=1. Sprawdźmy momenty w rozkładzie Gamma meanc(x); stdc(x)^2; skewn(x); Teoretyczne w rozkładzie są µ = αβ σ = αβ 2 2 2 γ 3 = α 7
Zobaczmy, czy dużo się mylimy. 2/sqrt(7); Żeby wygenerować zmienną z ogólnego rozkładu Gamma, należy zmienne przekształcić. X ~ gamma(1, β ) α X ~ gamma( α, β) np. Y=3*X; meanc(y); stdc(y)^2; skewn(y); Rozkład Chi-kwadrat Jedną z możliwości wygenerowania zmiennej z rozkładu chi-kwadrat o k stopniach swobody jest zsumowanie k kwadratów zmiennych z rozkładu normalnego X ~ N(0,1) n Q = X ~ chi kwadrat i= 1 2 i n Wygenerujmy zmienne z rozkładu chi-kwadrat o 3 stopniach swobody X=rndn(1000,3); /*3 kolumny zmiennych z rozkładu normalnego*/ Q=sumc(X'.^2); /*zsumowanie w wierszach poprzez sumę kolumn macierzy transponowanej*/ Podstawowe momenty zmiennej z rozkładu chi-kwadrat µ = k 2 σ 3 = 2k γ = 8/ k Policzmy momenty w próbie meanc(q); stdc(q)^2; skewn(q); 8
sqrt(8/3); 9
Zadania Zadanie 1. Na podstawie kodu poznanego na zajęciach proszę napisać funkcję robiącą eliminację Gaussa dla dowolnej macierzy kwadratowej (o dowolnych wymiarach). Zadanie 2. Napisać jeszcze jeden kod badający dla jak małego e macierz A A nie jest odwracalna. Użyj opcji while, ale uzależnij jej wykonywanie od wartości inv(a A), a nie od e. 1 1 1 1 e 0 0 0 A = 0 e 0 0 0 0 e 0 0 0 0 e Zadanie 3. Wczytać dane z pliku bos.xls do Gaussa i stworzyć wektor danych kursu zamknięcia. Zadanie 4. Napisać funkcję wczytującą do Gaussa dane z pliku txt, format jak z bossa.pl. Zadanie 4a. Wczytać dane z pliku UNIMIL.txt Zadanie 5. Napisać procedurę obliczającą kurtozę rozkładu Zadanie 6. Napisz funkcję obliczającą kwantyl dowolnego rzędu. Zadanie 7. Z pliku Unimil.txt obliczyć dzienną stopę zwrotu (jako różnicę logaytmów kursu zamknięcia) i obliczyć jej średnią, wariancję, kurtozę, skośność, medianę, kwantyle rzędu 0.05, 0.1, 0.15, 0.25, 0.75, 0.85, 0.9, 0.95 Zadanie 8. Wygeneruj 500 zmiennych z rozkładu normalnego (-4, 0.16). Zadanie 9. Wygeneruj 120 zmiennych z rozkładu jednostajnego U[-5,5]. Zadanie 10. Wygeneruj 1000 zmiennych losowych z rozkładu Poissona. Policz średnią, wariancję, skośność i kurtozę. 10
Zadanie 11. Wygeneruj 500 zmiennych z rozkładu chi-kwadrat o 30 stopniach swobody. Policz jej momenty Zadanie 12. Napisz procedurę generującą zmienne z rozkładu chi-kwadrat dla zadanej liczby stopni swobody 11