Uploaded by Teodor Iksinski

Wprowadzenie Do Scilaba

advertisement
Wprowadzenie do Scilaba
Bruno Pinçon
Institut Elie Cartan Nancy
E.S.I.A.L.
Université Henri Poincaré
Email :
Bruno.Pincon@iecn.u-nancy.fr
Przekªad z j¦zyka francuskiego
Piotr Fulma« ski
Katarzyna Szulc
Wydziaª Matematyki
Institut Elie Cartan Nancy
Universytetu Šódzkiego
Université Henri Poincaré
Email :
fulmanp@math.uni.lodz.pl
Email :
Katarzyna.Szulc@iecn.u-nancy.fr
Skrypt ten byª pocz¡ tkowo opracowany przez studentó w E.S.I.A.L. (École Supérieure d'Informatique
et Application de Lorraine). Opisuje on niewielk¡ cze±¢ mo» liwo± ci Scilaba, w szczgó lno± ci te, któ re
pozwalaj¡ zastosowa¢ notacje analizy numerycznej i maª ych symulacji stochastycznych takich jak:
operacje na macierzach i wektorach o wspóª rz¦ dnych rzeczywistych;
programowanie w Scilabie;
prosta graka;
niektó re funkcje dla dwó ch wymienionych powy» ej (generowanie liczb losowych, rozwiazywnie
ró wna« , ...).
¦nditemize Scilab umo» liwia wykonanie wielu innych operacji, w szczgó lno± ci
w dziedzinie automatyki, obró bki sygnaªó w dzwiekowych, symulacji systemó w dynamicznych
(za pomoc¡ scicos)... Jako » e zamierzam systematycznie uzupelnia¢ ten dokument, jestem w peª
ni otwarty na wszelkie uwagi, sugestie i krytyk¦ pozwalaj¡ ce mi na jego ulepszenie (ró wnie» w
przypadku bª¦ dó w ortogracznych), piszcie do mnie.
Maª a historia tego dokumentu:
wersja 0.999 : modykacje rozdziaª u o grace oraz uzupeª nienie tre± ci rozdziaª u o programowaniu; wersja relatywna do Scilab-2.7;
wersja 0.9999 (ten dokument) : dostosowanie rozdziaª u o grace do nowej graki obiektowej
Scilaba; wersja relatywna do Scilab-4.0. ¦nditemize
W wyniku dopisania kilku paragrafó w, dokument straciª na spó jno± ci.
Istnieje jednak
obecnie inny podr¦ cznik, któ ry jest dost¦ pny na stronie internetowej Scilaba (czytaj dalej).
¦m
Podzi¦ kowania
¦ndcenter
dla Doc Scilab, któ ry cz¦ sto pomagaª mi na forum u» ytkownikó w;
dla Bertranda Guiheneufa, któ ry dostarczyª mi magiczn¡ scierzk¦ do skompilowania
Scilaba 2.3.1 pod linuxem (kompilacja pod linuxem nowszych wersji nie powoduje prob-
1
lemó w);
1
dla moich kolegó w i przyjacióª Stéphane Mottelet , Antoine Grall, Christine BernierKatzentsev i Didier Schmitt;
dla Helmuta Jarauscha, któ ry przetª umaczyª ten dokument na j¦ zyk niemiecki, i któ ry
zwró ciª moj¡ uwag¦ na kilka bª edó w;
i dla wszystkich czytelnikó w za ich wsparcie, uwagi i korekty. ¦nditemize ¦ndtitlepage
dziekuje za ten pdf Stéphane !
2
Spis tre±ci
1
2
Wiadomo±ci wst¦pne
4
1.1
Co to jest Scilab? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
1.2
Jak korzystac z tego dokumentu? . . . . . . . . . . . . . . . . . . . . . . .
4
1.3
Podstawy pracy w Scilabie . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
1.4
Gdzie znale¹¢ informacje na temat Scilaba?
. . . . . . . . . . . . . . . . .
5
1.5
Jaki jest statut programu Scilab? . . . . . . . . . . . . . . . . . . . . . . .
6
Operacje na macierzach i wektorach
7
2.1
Wprowadzanie macierzy
7
2.2
Typowe wektory i macierze
. . . . . . . . . . . . . . . . . . . . . . . . . .
8
2.3
Wyra»enia w Scilabie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.1
Kilka podstawowych przykªadów wyra»e« macierzowych
. . . . . .
11
2.3.2
Dziaªania na elementach macierzy
. . . . . . . . . . . . . . . . . .
14
2.3.3
Rozwi¡zywanie ukªadów równa« liniowych . . . . . . . . . . . . . .
15
2.3.4
Indeksowanie, wydobywanie podmacierzy, konkatenacj macierzy i
wektorów
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
2.4
Informacje na temat ±rodowiska pracy(*) . . . . . . . . . . . . . . . . . . .
18
2.5
Wywoªanie pomocy z linii polece« . . . . . . . . . . . . . . . . . . . . . . .
19
2.6
Generator prostych wykresów . . . . . . . . . . . . . . . . . . . . . . . . .
19
2.7
Pisanie i wykonywanie skryptów
2.8
Dodatkowe informacje
. . . . . . . . . . . . . . . . . . . . . . .
20
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
2.8.1
Skracanie instrukcji przy zapisie macierzowym . . . . . . . . . . . .
21
2.8.2
Pozostaªe uwagi dotycz¡ce rozwi¡zywania ukªadów równa« liniowych
(*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9
3
2.8.3
Kilka prostych macierzy (*) . . . . . . . . . . . . . . . . . . . . . .
2.8.4
Funkcje
‚wiczenia
size i length
21
24
. . . . . . . . . . . . . . . . . . . . . . . . .
29
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
Programowanie w Scilabie
31
3.1
31
3.2
3.3
3.4
P¦tle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.1
P¦tla
3.1.2
P¦tla
for .
while
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
Instrukcja warunkowa
3.2.1
Instrukcja
3.2.2
Instrukcja
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
if-then-else .
select-case (*)
Inne rodzaje zmiennych
33
. . . . . . . . . . . . . . . . . . . . . .
33
. . . . . . . . . . . . . . . . . . . . . .
34
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
3.3.1
Ša«cuchy znaków . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
3.3.2
Listy (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
3.3.3
Niektóre wyra»enia z wektorami i macierzami typu logiczego (boolen) 40
Funkcje
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
3.4.1
Przekazywanie parametrów (*)
. . . . . . . . . . . . . . . . . . . .
44
3.4.2
Wy±wietlanie funkcji . . . . . . . . . . . . . . . . . . . . . . . . . .
44
3
3.5
3.6
Instrukcja
3.4.4
Kilka przydatnych dla funkcji prymitywów . . . . . . . . . . . . . .
Ró»ne ró»no±ci
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.2
Priorytety operatorów
. . . . . . . . . . . . . . . . . . . . . . . . .
49
3.5.3
Rekursja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51
3.5.4
Funkcja jest te» zmienn¡ . . . . . . . . . . . . . . . . . . . . . . . .
51
3.5.5
Okna dialogowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
3.5.6
Konwersja ªa«cucha znakowego do wyra»enia
. . . . . . . . . . . .
52
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
Wejscie i wyj±cie w stylu Fortranu
. . . . . . . . . . . . . . . . . .
53
Wej±cie i wyj±cie w stylu C
. . . . . . . . . . . . . . . . . . . . . . . . . .
57
3.8
Uwagi zwi¡zane z szybko±ci¡ . . . . . . . . . . . . . . . . . . . . . . . . . .
58
3.9
¢wiczenia
62
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Graka
64
4.1
Okna graczne
4.2
Wprowadzenie do
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
plot2
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
65
4.3
plot2d
4.4
Inne wersje
. . . . . . . . . . . . . . . . . . . .
71
4.5
Rysowanie wi¦kszej ilo±ci krzywych zªo»onych z ró»nej ilo±ci punktów . . .
72
4.6
Zabawa z kontekstem gracznym
. . . . . . . . . . . . . . . . . . . . . . .
73
4.7
Tworzenie histogramów
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
4.8
Zapisywanie graki w ró»nych formatach . . . . . . . . . . . . . . . . . . .
75
4.9
Prosta animacja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
z argumentami opcjonalnymi . . . . . . . . . . . . . . . . . . . . .
plot2d: plot2d2, plot2d3
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.1 Wprowadzenie do
plot3d
. . . . . . . . . . . . . . . . . . . . . . .
4.10.2 Kolory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.3
plot3d
z des facettes . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.4 Rysowanie powierzchni opisanej przy pomocy
y(u; v), z = z (u; v)
4.10.5
plot3d
x = x(u; v), y =
65
76
78
78
80
81
. . . . . . . . . . . . . . . . . . . . . . . . . . .
83
z interpolacj¡ kolorów . . . . . . . . . . . . . . . . . . . . .
85
4.11 Krzywe w przestrzeni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
4.12 Ró»no±ci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88
Zastosowania i uzupeªnienia
89
5.1
5.2
6
49
3.7
4.10 Powierzchnie
5
47
49
Dªugo±¢ identykatorów
Czytanie i pisanie . . .
. . . . . . . . . . . . . . . . . . . . . . . .
46
3.5.1
3.6.1
4
break
3.4.3
Równania ró»niczkowe
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ode
5.1.1
Podstawowe u»ycie
. . . . . . . . . . . . . . . . . . . . . . . .
5.1.2
Van der Pol jeszcze raz . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.3
Troche wi¦cej o
89
89
90
ode
. . . . . . . . . . . . . . . . . . . . . . . . . .
92
Generowniw liczb losowych
. . . . . . . . . . . . . . . . . . . . . . . . . .
94
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
5.2.1
Funkcja
5.2.2
Funkcja
rand .
grand
5.3
Dystrubuanty i ich odwrotno±ci . . . . . . . . . . . . . . . . . . . . . . . .
98
5.4
Proste symulacje stochastyczne
. . . . . . . . . . . . . . . . . . . . . . . .
99
5.4.1
Wprowadzenie i notacja
. . . . . . . . . . . . . . . . . . . . . . . .
99
5.4.2
Przedziaªy ufno±ci
5.4.3
Wykres dystrubuanty empirycznej
5.4.4
Test
5.4.5
Test Koªmogorowa-Smirnova
5.4.6
¢wiczenia
2
. . . . . . . . . . . . . . . . . . . . . . . . . . .
99
. . . . . . . . . . . . . . . . . .
101
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
102
. . . . . . . . . . . . . . . . . . . . .
103
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
104
Ciekawostki
107
4
6.1
Deniowanie wektora i macierzy wspóªczynnik po wspóªczynniku . . . .
107
6.2
Na temat warto±ci zwracanych przez funkcj¦ . . . . . . . . . . . . . . . . .
108
6.3
Funkcja zostaªa zmidykowana ale...
. . . . . . . . . . . . . . . . . . . . .
109
6.4
Problem z
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
109
6.5
Wektory wierszowe, wektory kolumnowe...
. . . . . . . . . . . . . . . . . .
109
6.6
Operator porównania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
109
6.7
Liczby zespolone a liczby rzeczywiste . . . . . . . . . . . . . . . . . . . . .
109
6.8
Proste instrukcje a funkcje Scilaba
. . . . . . . . . . . . . . . . . . . . . .
110
6.9
Obliczanie wyra»e« logicznych . . . . . . . . . . . . . . . . . . . . . . . . .
111
rand
A Odpowiedzi do ¢wicze« z rozdziaªu 2
112
B Rozwi¡zania ¢wicze« z rozdziaªu 3
114
C Rozwi¡zania ¢wicze« z rozdziaªu 4
118
5
Rozdziaª 1
Wiadomo±ci wst¦pne
1.1
Co to jest Scilab?
Dla osób znaj¡cych juz MATLAB-a odpowied¹ jest prosta Scilab jest jego darmowym
odpowiednikiem (wi¦cej szczeguªów zwi¡zanych z tym tematem w dalszej cz¦±ci), pow-
1 w I.N.R.I.A. (Institut National de Recherche en Informatique et Automatique).
staªym
Skªadnia, z wyj¡tkiem nielicznych polece«, jest taka sama (istotne ró»nice wyst¦puj¡
w przypadku graki).
Osobom nie znajacym MATLABA powiem tylko, ze Scilab jest
przyst¦pnym ±rodowiskiem do wykonywania oblicze« numerycznych gdy» dysponuje on
odpowiednimi metodami w tym zakresie:
rozwiazywanie ukladów liniowych,
wyznaczanie warto±ci wªasnych, wektoró w wªasnych,
dekompozycja dla warto±ci osobliwych i pseldo-osobliwych,
szybka transformacja Fouriera,
rozwiazywanie równa« ró»niczkowych,
algorytmy optymalizacji,
rozwiazywanie równa« nieliniowych,
generowanie liczb losowych,
dla wielu niezaawansowanych zastosowa« algebry liniowej w automatyce.
Ponadto Scilab wyposa»ony jest w funkcje slu»¡ce do tworzenia graki, zarówno niskopoziomowej
(wielok¡ty, odczytywanie wspóªrz¦dnych poªo»enia kursora, itp.) jak i wysokopoziomowej
(krzywe, powierzchnie itp.). Wprowadzony j¦zyk programowania, dzi¦ki operowaniu notacj¡ macierzow¡, jest prostym, ale pot¦»nym i efektywnym narz¦dziem. Wyszukiwanie
bª¦dów w programach jest szybkie dzi¦ki ªatwemu operowaniu zmiennymi. W przypadku,
gdy obliczenia b¦d¡ zbyt czasochªonne (j¦zyk jest interpretowany. . . ) mo»liwe jest ªatwe
poª¡czenie programu Scilaba z podprogramami napisanymi w C czy FORTRAN-ie.
1.2
Jak korzystac z tego dokumentu?
W rozdziale drugim wyja±nione zostaªy podstawy pracy z Scilabem jako narzedziem do
obliczen macierzowych. Wystarczy przesledzic proponowane przyklady. Sekcje oznaczone
gwiazdk¡ podczas pierwszego czytania mo»na pomin¡¢. Osoby zainteresowane zagadnieniami dotycz¡cymi graki, mog¡ przeanalizowa¢ pierwsze przykªady z rozdziaªu czwartego.
Rozdziaª trzeci wyja±nia podstawy programowania w Scilabie.
Zacz¡ªem pisa¢ rozdziaª
pi¡ty, który przedstawia niektóre zastosowania podobnie jak rozdziaª Ciekawostki, który
przedstawia najcz¦±ciej popeªniane bª¦dy przez u»ytkowników Scilaba (prze±lij mi równie»
Twoje!). Ostatnim aspektem jest ±rodowisko graczne. Istniej¡ nieznaczne ró»nice pomi¦dzy
1
Scilab wyko»ystuje du»¡ ilo±¢ funkcji pochodz¡cych z ró»nych miejsc, dostepnych czesto przez Netlib
6
±rodowiskami gracznymi przeznaczonymi dla Unix i Windows, polegaj¡ce na odmennym
sposobie rozmieszczenia przycisków i menu. W tym dokumencie opieram si¦ na wersji Unix
aczkolwiek u»ytkownicy wersji przeznaczonej dla systemu Windows nie powinni natra¢
na problemy ze znalezieniem odpowiednich opcji / przyciskow.
1.3
Podstawy pracy w Scilabie
W najprostszym przypadku, Scilab mo»e byc wykorzystywany jako kalkulator zdolny
wykonywa¢ obliczenia na wektorach i macierzach liczb rzeczywistych i/lub zespolonych
(ale tak»e na zwykªych skalarach) oraz do wizualizacji krzywych i powierzchni.
W na-
jprostrzych zadaniech raczej nie ma potrzeby pisania programow. Dosy¢ szybko zaczniemy
jednak korzysta¢ ze skryptów (zbiorów instrukcji, polece« Scilaba) a nastepnie funkcji.
Oczywi±cie niezb¦dne w takich sytuacjach staje si¦ u»ycie edytora tekstu, na przykªad
emacs (Unix, Windows), wordpad (Windows), vi lub vim (Unix)...
Scilab posiada ak-
tualnie wªasny, zintegrowany edytor (scipad), który mo»e równie» sªó»y¢ jako
debuger dla funkcji.
1.4
Gdzie znale¹¢ informacje na temat Scilaba?
W dalszej cz¦±ci dokumentu zakªada si¦, i» czytelnik dysponuje wersj¡ 4.0
programu. W celu uzyskania dodatkowych informacji odsyªam do Scilab home
page:
http://scilabsoft.inria.fr
na której znale¹¢ mo»na ró»norodn¡ dokumentacj¦ oraz efekty pracy innych
u»ytkowników.
Scilab group wydaªa (w latach 1999 2001) okoªo dwudziestu artykuªów w
czasopi±mie Linux magazie. S¡ one szczególnie polecane przez autora, gdy»
poruszaj¡ wi¦kszo±¢ zagadnie« zwi¡zanych z Scilabem (wiekszo±ci z nich w
tym opracowaniu nawet si¦ nie porusza). Uzyska¢ je mo»na pod adresem
http://www.saphir-control.fr/articles/
Na temat Scilaba prowadzone jest równie» forum dyskusyjne, w ramach którego
istnieje mo»liwo±¢ zadawania pyta«, dokonywania uwag, udzielania odpowiedzi
na wcze±niej postawione pytania, itd:
comp.sys.math.scilab
Wszystkie zamieszczone tam wiadomo±ci s¡ archiwizowane i dostepne ze strony
Scilab newsgroup archive.
Wybieraj¡c jeden z dwóch odsyªaczy Books and Articles on Scilab lub Scilab Related
Links umieszczonych na stronie gªównej uzyskujemy dost¦p do wielu ró»nych
domowej Scilaba po wybraniu
dokumentów. W szczególnosci:
wprowadzenie B. Ycart (Démarrer en Scilab et statistiques en Scilab);
Scilab Bag Of Tricks autorstwa Lydia E. van Dijk i Christoph L. Spiel,
który jest raczej przeznaczony dla osób dobrze znajacych ju» Scilaba (rozwój
tej ksi¡»ki zostaª niestety brutalnie przerwany kilka lat temu);
Travaux Pratiques sur Scilab classes par themes
umo»liwia dost¦p do projektów
realizowanych przez studentøw ENPC;
wprowadzenie do informatyki z u»yciem Scilab-a (verb+http://kiwi.emse.fr/SCILA
Oczywi±cie w zale»no±ci od potrzeb znale¹¢ mo»na wiele innych opracowa«
traktuj¡cych problem w nieco odmienny ni» zamieszczony tutaj sposób.
7
1.5
Jaki jest statut programu Scilab?
Osoby dobrze znaj¡ce oprogramowanie na licencji GPL z pewno±ci¡ interesuje
statut Scilaba jako programu darmowego. Oto jak na ten temat wypowiada
si¦ Doc na forum:
Scilab: is it really free?
Yes it is.
Scilab is not distributed under GPL or other standard free soft-
ware copyrights (because of historical reasons), but Scilab is an Open Source
Software and is free for academic and industrial use, without any restrictions.
There are of course the usual restrictions concerning its redistribution; the
only specic requirement is that we ask Scilab users to send us a notice (email
is enough). For more details see Notice.ps or Notice.tex in the Scilab package.
Answers to two frequently asked questions: Yes, Scilab can be included a commercial package (provided proper copyright notice is included). Yes, Scilab can
be placed on commercial CD's (such as various Linux distributions). Nie mniej
jednak Scilab obecnie nie odpowiada kryteriom FSF czy OSI aby móc by¢ traktowany jako program darmowy ze wzgl¦du na to, »e nie mo»na rozprowadz¢
wersji zmodykowanych (bez autoryzacji ze strony INRIA). Mimo to, dzi¦ki
swojemu statutowi, Scilab pozostanie w przyszªo±ci programem darmowym
wraz ze swoimi plikami ¹ródªowymi. Z drugiej strony zanosi si¦ na to, »e korsorcjum Scilab-a otrzyma licencj¦ typu GPL lub LGPL patrz CECILL, i »e ...
tutu
8
Rozdziaª 2
Operacje na macierzach i wektorach
Ta cz¦±¢ daje podstawy do poznania zastosowa« Scilaba jako narz¦dzia do
operacji macierzowych.
Aby rozpocz¡¢ prac¦ ze Scilaben wystarczy wpisa¢
scilab
w terminalu1 Je±li wszystko przebiega prawidªowo, na ekranie uka»e si¦ okno
Scilaba z gªównym menu zawieraj¡cym w szczególno±ci przyscisk
Help, Demos
a w oknie wprowadzania polece« uka»e si¦
------------------------------------------scilab-4.0
Copyright (c) 1989-2006
Consortium Scilab (INRIA, ENPC)
------------------------------------------Startup execution:
loading initial environment
-->
gdzie
2.1
-->
jest znakiem zach¦ty.
Wprowadzanie macierzy
Podstawowym typem danych w Scilabie jest macierz liczb rzeczywistych lub
zespolonych. Najprostszym sposobem deniowania macierzy (wektora, skalara
b¦d¡cych w istocie szczególnymi przypadkami macierzy) w ±rodowisku Scilab
jest wprowadzenie z klawiatury listy elementów macierzy, stosuj¡c nast¦puj¡c¡
konwencj¦:
elementy tego samego wiersza oddzielone s¡ spacj¡ lub przecinkiem;
lista elementów musi by¢ uj¦ta w nawias kwadratowy [];
ka»dy wiersz, z wyj¡tkiem ostatniego, musi by¢ zako«czony ±rednikiem.
Dla przykªadu komenda:
-->A=[1 1 1;2 4 8;3 9 27]
da na wyj±ciu
1
Albo klikn¡c odpowiedni¡ ikon¦.
9
A
!
!
!
=
1.
2.
3.
1.
4.
9.
1. !
8. !
27. !
i oczywiscie macierz zostanie zachowana w pami¦ci.
W przypadku, gdy in-
strukcja zostanie zako«czona ±rednikiem, wynik nie pojawi si¦ na ekranie.
Wpiszmy na przykªad
-->b=[2 10 44 190];
aby zobaczy¢ wspóªrz¦dne wprowadzonego wektora, wystarczy napisa¢
-->b
a odpowiedzi¡ b¦dzie
b =
! 2.
10. 44.
190. !
Bardzo dªuga instrukcja mo»e by¢ napisana w kilku liniach, przy czym przechodz¡c do nast¦pnej linii, lini¦ poprzedni¡ nale»y zako«czy¢ trzema kropkami,
jak w poni»szym przykªadzie:
-->T = [ 1 0 0 0 0 0
-->
1 2 0 0 0 0
-->
1 2 3 0 0 0
-->
1 2 3 0 0 0
-->
1 2 3 4 0 0
-->
1 2 3 4 5 0
-->
1 2 3 4 5 6
;...
;...
;...
;...
;...
;...
]
co daje
T
!
!
!
!
!
!
=
1.
1.
1.
1.
1.
1.
0.
2.
2.
2.
2.
2.
0.
0.
3.
3.
3.
3.
0.
0.
0.
4.
4.
4.
0.
0.
0.
0.
5.
5.
0.
0.
0.
0.
0.
6.
!
!
!
!
!
!
W przypadku wprowadzania liczb zespolonych stosuje si¦ nast¦puj¡c¡ skªadnie:
-->c=1 + 2*%i
c =
1. + 2.i
-->Y = [ 1 + %i , -2 + 3*%i ; -1 , %i]
Y =
! 1. + i
- 2. + 3.i !
! - 1.
i
!
2.2
Typowe wektory i macierze
Istniej¡ funkcj¦ do konstrukcji typowych macierzy i wektorów zatem przedstawiam tu jedn¡ z pierwszych list (jest ich wi¦cej, o których mówimy w dalszej
cz¦±ci lub które mo»na znale¹¢ w Pomocy).
Macierz jednostkowa
Aby otrzyma¢ macierz jednostkow¡ o wymiarach 4 na 4 stosujemy instrukcj¦:
10
-->I=eye(4,4)
I =
! 1.
0.
! 0.
1.
! 0.
0.
! 0.
0.
0.
0.
1.
0.
Argumentami funkcji
: je»eli
n<m
0. !
0. !
0. !
1. !
eye(n,m)
(odpowiednio
jest liczba wierszy (n) oraz kolumn (m) (Uwaga
n > m)
wówczas otrzymamy macierz odwzorowa-
nia wzajemnie jednoznacznego, surjekcja (odpowiednio injekcja) przestrzeni
kanonicznej
Km na Kn.)
Macierz diagonalna, wyciecie cz¦±ci diagonalnej macierzy
Aby otrzyma¢ macierz diagonaln¡, w której elementy na gªównej przek¡tnej
pochodz¡ z wcze±niej zdeniowanego wektora
-->B=diag(b)
B =
! 2.
0.
! 0.
10.
! 0.
0.
! 0.
0.
Uwaga: Pisz¡c
0.
0.
44.
0.
b
0.
0.
0.
190.
b
wpisujemy
!
!
!
!
nadal mamy dost¦p do wcze±niej zdeniowanego wektora, co
pokazuje, »e Scilab rozró»nia wielko±¢ liter.
Zastosowanie na macierzy funkcji
diag
pozwala uzyska¢ gªówn¡ przek¡tn¡
macierzy jako wektor kolumnowy
-->b=diag(B)
b =
! 2. !
! 10. !
! 44. !
! 190. !
(Funkcja ta przyjmuje tak»e drugi, opcjonalny, argument porównaj ¢wiczenia.)
Macierze zerowa i jedynkowa
zeros i ones pozwalaj¡ odpowiednio stworzy¢ macierze zerowe i macierze
skªadaj¡ce si¦ z jedynkek. Podobnie jak dla funkcji eye ich argumentami s¡
Fnkcje
liczba wierszy i liczba kolumn.
-->C = ones(3,4)
C =
! 1.
1.
1.
! 1.
1.
1.
! 1.
1.
1.
1. !
1. !
1. !
Mo»na tak»e u»y¢ jako argument nazw¦ macierzy ju» zdeniowanej w ±rodowisku.
W efekcie otrzymujemy macierz o takich samych wymiarach co macierz b¦d¡ca
argumentem
-->O = zeros(C)
O =
! 0.
0.
0.
! 0.
0.
0.
! 0.
0.
0.
0. !
0. !
0. !
11
Macierz trójk¡tna
triu i tril pozwalaj¡
-->U = triu(C)
U =
! 1.
1.
1.
1. !
! 0.
1.
1.
1. !
! 0.
0.
1.
1. !
Funcje
otrzyma¢ macierz trójk¡tn¡ górn¡ i doln¡:
Macierze o elementach losowych
Funkcja
rand pozwala utworzy¢ macierz o elementach peudolosowych (pochodz¡-
cych z przedziaªu [0,1); mo»liwe jest tak»e u»ycie rozkªadu normalnego jak i
podanie zarodka dla generatora liczb pseudolosowych):
-->M = rand(2, 6)
M =
! 0.2113249
0.0002211
! 0.7560439
0.3303271
0.6653811
0.6283918
0.8497452
0.6857310
0.8782165
0.0683740
0.5608486 !
0.6623569 !
n elementowy wektor o staªej ró»nicy mi¦dzy elementami
x o n wspóªrz¦dnych równomiernie rozmieszczonych pomi¦dzy x1 i xn (innymi sªowy tak aby xi+1
xi = xnn 1x1 , n w¦zªów,
zatem n
1), u»ywamy funkcji linspace.
-->x = linspace(0,1,11)
x =
! 0.
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1. !
Aby wprowadzi¢ wektor (wierszowy)
Instrukcj¡ analogiczn¡ pozwalaj¡c¡ utworzy¢ wektor o zadanej warto±ci pierwszej wspóªrz¦dnej, ustalonej ró»nicy pomi¦dzy wspóªrz¦dnymi i ostatniej
wspóªrz¦dnej nie wi¦kszej ni» zadana warto±¢ jest
-->y = 0:0.3:1
y =
! 0.
0.3
0.6
0.9 !
Skªadnia jest nast¦puj¡ca y = wartosc_poczatkowa:przyrost:wartosc_graniczna.
Dok¡d pracujemy z liczbami caªkowitymi nie ma problemu z ustaleniem warto±ci
granicznej odpowiadaj¡cej ostatniej skªadowej wektora.
-->i = 0:2:12
i =
! 0.
2.
4.
6.
8.
10.
12. !
Dla liczb rzeczywistych jest to zdecydowanie trudniejsze do okre±lenia:
(i) przyrost mo»e posiad¢ niesko«czone rozwini¦cie w reprezentacji binarnej
lub jego sko«czone rozwini¦cie mo»e wybiega¢ poza zakres reprezentacji
maszynowej liczb rzeczywistych powoduj¡c ich zaokr¡glenia;
(ii) bª¦dy zaokr¡gle« numerycznych kumuluj¡ si¦ w miar¦ obliczania kolejnych
skªadowych wektora.
-->xx = 0:0.05:0.60
ans =
! 0. 0.05 0.1 0.15
0.2
0.25
0.3
0.35
0.4
0.45
0.5
0.55 !
Uwaga: w zale»no±ci od komputera na jakim uruchomiony zostanie Scilab
powy»szy przykªad mo»e da¢ ró»nie wyniki, to znaczy 0:6 mo»e pojawi¢ si¦
jako ostatnia skªadowa.
Cz¦sto przyrost równy jest
1,
mo»na go w takiej sytuacj pomin¡¢:
12
-->ind = 1:5
ind =
! 1.
2.
3.
4.
5. !
W przypadku gdy przyrost jest dodatni (ujemny) oraz
wartosc_poczatkowa>wartosc_gra
(wartosc_poczatkowa<wartosc_granczna) otrzymujemy wektor bez wspóªrz¦dnych
(!)
nazywany w Scilabie macierz¡ pust¡ (patrz sekcja niektóre dodatkowe
proste macierze):
-->i=3:-1:4
i =
[]
-->i=1:0
i =
[]
2.3
Wyra»enia w Scilabie
Scilab jest j¦zykiem posiadaj¡cym bardzo prost¡ skªadni¦ (patrz rozdziaª nast¦pny),
w której instrukcja przypisania ma posta¢
zmienna = wyrazenie
lub pro±ciej
wyrazenie
gdzie w ostatnim przypadku warto±¢
zmiennej o nazwie
ans.
wyrazenia
jest przypisana do domy±lnej
Wyra»enia w Scilabie mog¡ by¢ tak proste (je±li chodzi
o zapis) jak wyra»enia skalarne w innych j¦zykach programowania, ale mog¡
skªada¢ si¦ z macierzy i wektorów co cz¦sto sprawia trudno±¢ pocz¡tkujacym
u»ytkownikom tego j¦zyka. Dla wyra»e« skalarnych mamy standardowe operatory +, -, * , / i ^ i najcz¦±ciej stosowane funkcje przedstawione w tabeli2
2.1.
Deniuj¡c zmienn¡ (b¦d¡c¡ skalarem, wektorem, macierz¡) jej warto±¢ (warto±ci)
nie musi by¢ wyra»ona przez konkretn¡ liczb¦, ale tak»e przez wyra»enie
którego warto±¢ zostanie jej przypisana.
-->M = [sin(%pi/3) sqrt(2) 5^(3/2) ; exp(-1) cosh(3.7) (1-sqrt(-3))/2]
M =
! 0.8660254
1.4142136
11.18034
!
! 0.3678794
20.236014
0.5 - 0.8660254i !
Uwaga: Powy»szy przykªad ilustruje potencjalne niebezpiecze«stwo podczas
obliczania pierwiastka kwadratowego z liczy ujemnej. Scilab rozwa»a czy ma
do czynienia z liczbami zespolonymi i zwraca jeden z pierwiastów jako rezultat.
2.3.1 Kilka podstawowych przykªadów wyra»e« macierzowych
Dost¦pne s¡ wszystkie proste dziaªania wykonywane na macierzach:
suma
dwóch macierzy, iloczyn macierzy, iloczyn skalarny i macierzowy itd. Oto kilka
przykªadów (w których wykorzystujemy wcze±niej zdeniowane macierze). Uwaga:
Tekst wyst¦pujacy w danym wierszu po znaku // oznacza dla Scilab-a komentarz. Nie jest interpretowany a jedynie dostarcza pewnych uwag i wyja±nie«
osobie czytaj¡cej kod.
2
Scilab dysponuje innymi funkcjami matematycznymi takimi jak funkcje Legendra, funkcje Bessela, funkcje eliptyczne,
itd. . . oraz funkcje odnosz¡ce sie do znanych rozkªadów prawdopodobie«stwa (dystrybuanty i ich odwrotno±ci)
13
abs
exp
log
log10
cos
sin
sinc
tan
cotg
acos
asin
atan
cosh
sinh
tanh
acosh
asinh
atanh
sqrt
floor
ceil
int
erf
erfc
gamma
lngamma
dlgamma
warto±¢ bezwzgl¦dna, moduª
eksponent
logarytm naturalny
logarytm o podstawie 10
cosinus (argument w radianach)
sinus (argument w radianach)
sin(x)
x
tangente (argument w radianach)
cotangente (argument w radianach)
arccos
arcsin
arctg
cosinus hiperboliczny
sinus hiperboliczny
tangens hiperboliczny
argch
argsh
argth
pierwiastek kwadratowy
E (x) = (bxc) = n , n x < n + 1;
x2N
dxe = n , n 1 < x n; x 2 N
int(x) = bxc je±li x > 0 oraz
= dxe dla x 0
2 R x e t2 dt
funkcja bª¦du erf (x) = p
0
R
dopeªnienie funkcji bª¦du okre±lone przez ercf (x) = 1
erf (x) = p2 x+1 e t2 dt
R
(x) = 0+1 tx 1 e t dt
ln( (x))
d
dx ln( (x))
Tablica 2.1: Wybrane funkcj u»ywane przez Scilaba.
-->D = A + ones(A)
D =
! 2.
2.
2.
! 3.
5.
9.
! 4.
10.
28.
// napisz A aby zobaczyc wczesniejsza zawartosc macierzy
!
!
!
-->A + M
// nie mozna wykonac dzialania dodawania (niezgodnosc wymiaro
!--error
8
inconsistent addition
-->E = A*C
E =
! 3.
3.
! 14.
14.
! 39.
39.
// C jest macierza (3,4) zlozona z elementow o wartosci 1.0
3.
14.
39.
3. !
14. !
39. !
--> C*A // nie mozna wykonac mnozenia (niezgodnosc wymiarow): jaka jest odpowied
!--error
10
inconsistent multiplication
--> At = A'
// transpozycje otrzymuje sie stawiajac za nazwa macierzy znak apostr
14
At
!
!
!
=
1.
1.
1.
-->
Ac
!
!
!
Ac = A + %i*eye(3,3)
=
1. + i
1.
2.
4. + i
3.
9.
2.
4.
8.
3. !
9. !
27. !
// tworzymy macierz o elementach zespolonych
1.
8.
27. + i
!
!
!
--> Ac_adj = Ac' // w ten sposob otrzymujemy macierz transponowana o elementach ze
Ac_adj =
! 1. - i
2.
3.
!
! 1.
4. - i
9.
!
! 1.
8.
27. - i
!
-->x = linspace(0,1,5)' // konstrukcja wektora kolumnowego
x =
! 0. !
! 0.25 !
! 0.5 !
! 0.75 !
! 1. !
-->y =
y =
! 1.
! 2.
! 3.
! 4.
! 5.
(1:5)' // inny wektor kolumnowy
!
!
!
!
!
-->p = y'*x
p =
10.
-->Pext =
Pext =
! 0.
! 0.
! 0.
! 0.
! 0.
--> Pext
ans =
! 0.
! 0.
! 0.
! 0.
! 0.
// iloczyn skalarny wektorow x i y
y*x' // otrzymujemy macierz 5x5 rzedu 1, dlaczego?
0.25
0.5
0.75
1.
1.25
/ 0.25
1.
2.
3.
4.
5.
0.5
1.
1.5
2.
2.5
0.75
1.5
2.25
3.
3.75
1.
2.
3.
4.
5.
!
!
!
!
!
// macierz mozna podzielic przez skalar
2.
4.
6.
8.
10.
3.
6.
9.
12.
15.
4.
8.
12.
16.
20.
15
!
!
!
!
!
--> A^2
ans =
! 6.
! 34.
! 102.
// podniesienie do potegi drugiej macierzy
14.
90.
282.
36. !
250. !
804. !
--> [0 1 0] * ans
// mozna uzyc zmiennej ans, ktora zawiera wynik ostatniego dzi
-->
// przypisany do zadnej zmiennej
ans =
! 34.
90.
250. !
--> Pext*x - y + rand(5,2)*rand(2,5)*ones(x) + triu(Pext)*tril(Pext)*y;
--> // wpisz ans aby zobaczyc wynik
Inn¡, bardzo interestuj¡c¡ cech¡ charakterystyczn¡, jest mo»liwo±¢ podania
jako argumentu dla funkcji (z tabeli 2.1) macierzy zamiast kolejnych jej ele-
f(A) oznacza obliczenie warto±ci
A; otrzymamy sób macierz [f (aij )].
mentóws. Innymi sªowy wpisanie instrukcji
funkcji
f
na kolejnych elementach macierzy
Przykªady:
-->sqrt(A)
ans =
! 1.
! 1.4142136
! 1.7320508
1.
2.
3.
-->exp(A)
ans =
! 2.7182818
! 7.3890561
! 20.085537
2.7182818
54.59815
8103.0839
1.
!
2.8284271 !
5.1961524 !
2.7182818 !
2980.958 !
5.320D+11 !
Uwaga: dla funkcji, które maj¡ sens dla macierzy (co innego dla funkcji które
stosuje si¦ dla ka»dego elementu macierzy. . . ) na przyklad funkcja eksponent,
nazwa funkcji jest poprzedzona liter¡ m w ten sposób aby otrzyma¢ eksponent
macierzy A wystarczy wprowadzi¢ komend¦ expm
2.3.2 Dziaªania na elementach macierzy
Aby pomno»y¢ lub podzieli¢ dwie macierze, A i B, o tych samych wymiarach,
w taki spsób aby wynikiem byªa macierz, równie» o tych samych wymiarach,
w której ka»dy element jest iloczynem (ilorazem) odpowiednich elementów
macierzy A i B nale»y u»yc operatorów
mentach
[aij bij ]
natomiast
A./B
.*
lub
./. A.*B
jest macierz¡ o ele-
jest macierz¡ o elementach
[aij =bij ].
Podobnie
mo»na podnie±¢ do pot¦gi ka»dy z elementów macierzy wpisuj¡c operator
A.^p pozwoli otrzyma¢ macierz o wyrazach [apij ]. Rozwa»my przykªad:
-->A./A
ans =
! 1. 1. 1. !
! 1. 1. 1. !
! 1. 1. 1. !
.^:
Uwagi:
W przypadku gdy A nie jest macierz¡ kwadratow¡ dziaªanie A^n b¦dzie
16
wykonywane na kolejnych elementach macierzy A. Zaleca si¦ jednak stosowanie
zapisu A.^n poniewa» jest on bardziej czytelny.
Je±li s jest skalarem oraz A jest macierz¡ wówczas s.^A daje macierz o
wyrazach saij .
2.3.3 Rozwi¡zywanie ukªadów równa« liniowych
Aby rozwi¡za¢ ukªad równa« liniowych gdzie macierz wspóªczynników jest
kwadratowa, Scilab stosuje rozkªad LU z cz¦±ciow¡ zamian¡ wierszy prowadz¡c¡
do rozwiazania dwóch trójk¡tnych ukªadów równa«. Jest to jednak operacja
niewidoczna dla u»ytkownika dzi¦ki wyko»ystaniu operatora
-->b=(1:3)'
b =
! 1. !
! 2. !
! 3. !
// tworzymy wektor b
-->x=A\b
x =
! 1. !
! 0. !
! 0. !
// rozwiazujemy Ax=b
-->A*x - b
ans =
! 0. !
! 0. !
! 0. !
\:
// sprawdzamy poprawnosc wyniku
Aby zapami¦ta¢ ten sposób post¦powania, nale»y mie¢ na uwadze ukªad pocz¡tkowy
Ax = b a nast¦pnie pomno»y¢ ukªad lewostronnie przez A 1 (co oznacza podzielenie przez macierz A). Sposób ten daje dokªadny wynik, ale w ogólno±ci wys-
t¦puj¡ bª¦dy zaokr¡glenia spowodowane arytmetyk¡ liczb zmiennoprzecinkowych.
-->R = rand(100,100); // stawiamy srednik na koncu aby uniknac zalewu ekranu licz
-->y = rand(100,1);
// jak wyzej
-->x=R\y;
// rozwiazanie ukladu Rx=y
-->norm(R*x-y)
ans =
1.134D-13
// funkcja norm pozwala obliczyc norme wektorow (macierzy)
// (obliczyc mozemy dwie normy -- euklidesowa i hermitea)
Uwaga: Nie otrzymacie wyniku identycznego z moim je»eli funkcja rand nie
zostanie u»yta tak jak w powy»szym przykªadzie. . . W momencie gdy rozwi¡zanie
ukªadu liniowego jest w¡tpliwe, Scilab wy±wietla informacje ostrzegaj¡ce i pozwalaj¡ce podj¡¢ odpowiednie w takiej sytuacji dziaªania.
2.3.4 Indeksowanie, wydobywanie podmacierzy, konkatenacj macierzy
i wektorów
Aby odniesc si¦ do konkretnego elemetnu macierzy wystarczy przy nazwie
poda¢ w nawiasie jego indeksy. Na przykªad:
17
-->A33=A(3,3)
A33 =
27.
-->x_30 = x(30,1)
x_30 =
- 1.2935412
-->x(1,30)
!--error
invalid index
21
-->x(30)
ans =
- 1.2935412
Uwaga: Je»eli macierz jest wektorem kolumnowym wystarczy jedynie wpisa¢
numer linii, w której znajduje si¦ szukany element; analogicznie post¦pujemy
w przypadku wektora wierszowego.
Zalet¡ j¦zyka Scilab jest mo»liwo±¢ ªatwego wydobywanie podmacierzy z macierzy
wyj±ciowej.
-->A(:,2)
ans =
! 1. !
! 4. !
! 9. !
// aby uzyskac 2 kolumne,...
-->A(3,:) // ... 3 wiersz
ans =
! 3.
9.
27. !
-->A(1:2,1:2) // podmacierz glowna rzedu 2
ans =
! 1.
1. !
! 2.
4. !
Omówmy teraz ogóln¡ skªadni¦. Niech macierz
dalej
v1 = (i1 ; : : : ; ip )
oraz
v2 = (j1 ; : : : ; jq )
oznacza macierz o wymiarach
odpowiadaj¡cych wierszom
-->A([1 3],[2 3])
ans =
! 1.
1. !
! 9.
27. !
i1 ; i2 ; : : : ; ip
ma wymiary
(n:m),
niech
oznaczaj¡ wektory (wierszowe lub
kolumnowe), w których warto±ci s¡ takie, »e
A(v1,v2)
A
1 ik n
et
1 jk m,
wówczas
(p; q) utworzon¡ z wyrazów macierzy A
j1 ; j2 ; : : : ; jq .
oraz kolumnom
-->A([3 1],[2 1])
ans =
! 9.
3. !
! 1.
1. !
W praktyce dokonujemy prostrzych ekstrakcji, wydobywa si¦ elementy umieszczone w przylegaj¡cych blokach na przykªad w kolumnach lub wierszach. W
takim przypadku u»yjemy wyra»enia
i_poczatkowe:przyrost:i_koncowe
w celu
wygenerowania wektora wska¹ników. Natomiast aby wygenerowa¢ peªny ob18
szar odpowiadaj¡cy wymiarowi u»yjemy operatora
:
(jak wida¢ to w pier-
wszym przykªadzie). Zatem aby otrzyma¢ podmacierz zªo»on¡ z 1 i 3 wiersza
zastosujemy
-->A(1:2:3,:)
ans =
! 1.
1.
! 3.
9.
// lub inaczej A([1 3],:)
1. !
27. !
Przejd¹my teraz do operacji konkatencaji macierzy, która umo»liwia poª¡czenie (ustawiaj¡c obok siebie) wiele macierzy w celu otrzymania jednej zwanej
macierz¡ blokow¡. Dla przykªadu rozwa»my nast¦puj¡c¡ macierz podzielon¡
01 2 3 4 1
B 1 4 9 16 C
A=B
@ 1 8 27 64 C
A
na bloki:
=
1 16 81 256
Nale»y zatem zdeniowa¢ podmacierze
-->A11=1;
A11 A12
A21 A22
:
A11 ; A12 ; A21 ; A22 :
-->A12=[2 3 4];
-->A21=[1;1;1];
-->A22=[4 9 16;8 27 64;16 81 256];
ostatecznie otrzymujemy macierz
-->A=[A11 A12;
A =
! 1. 2. 3.
! 1. 4. 9.
! 1. 8. 27.
! 1. 16. 81.
A21 A22]
4.
16.
64.
256.
A powstaª¡ z poª¡czenia 4 bloków:
!
!
!
!
Z punktu widzenia syntaktyki, macierze blokowe traktowane s¡ jak zwykªe
skalary (nale»y przy tym oczywi±cie pami¦ta¢ o zgodno±ci wymiarów odpowidnich macierzy blokowych).
Istnieje odr¦bna skªadnia sªu»¡ca do jenoczesnego usuni¦cia z macierzy wierszy lub kolumn: niech
v = (k1 ; k2 ; : : : ; kp
numerów wierszy lub kolumn macierzy
usuni¦cie wierszy o numerach
usunie kolumny
kolumnowym),
k1 ; k2 ; : : : ; kp .
u(v)=[]
b¦dzie wektorem skªadaj¡cym si¦ z
M.
k1 ; k2 ; : : : ; kp
Polecenie
z macierzy
Ponadto je±li
u
M(v,:)=[]
M,
spowoduje
natomiast
M(:,v)=[]
jest wektorem (wierszowym lub
usunie odpowiednie skªadowe.
Kolejno±¢ elementów macierzy
Macierze w Scilabie s¡ skªadowane kolumna za kolumn¡ i ta kolejno±¢ elementów wykorzystywana jest w wielu funkcjach (porównaj dla przykªadu
polecenie
matrix,
która umo»liwia zmian¦ wymiarów macierzy). W szczegól-
no±ci dla operacji wstawiania i wydobywania mo»liwe jest u»ycie domy±lnego
porz¡dku przy wykorzystaniu jednynie pojedy«czego wektora indeksów (w
miejsce dwóch, jako wska¹nik kolumn lub wierszy).
opartych na wcze±niej zdeniowanej macierzy
-->A(5)
ans =
19
A:
Oto kilka przykªadów
2.
-->A(5:9)
ans =
! 2. !
! 4. !
! 8. !
! 16. !
! 3. !
-->A(5:9)
A =
! 1. ! 1. ! 1. ! 1. 2.4
= -1
1.
1.
1.
1.
// spowoduje wstawienie elementu o wartosci -1
- 1.
9.
27.
81.
4.
16.
64.
256.
!
!
!
!
Informacje na temat ±rodowiska pracy(*)
Wystarczy wpisa¢
who
a otrzymamy w ten sposób nast¦puj¡ce informacje
-->who
your variables are...
Anew
A
A22
A21
A12
A11
x_30
A33
x
y
R
b
Pext
p
Ac_adj
Ac
At
E
D
cosh
ind
xx
i
linspace M
U
O
zeros
C
B
I
Y
c
T
startup i
scicos_pal
home
PWD
TMPDIR
percentlib
fraclablib
soundlib xdesslib utillib
tdcslib
siglib
s2flib
roblib
optlib
m
elemlib commlib polylib autolib armalib alglib
mtlblib SCI
%
%T
%z
%s
%nan
%inf
old
newstacksize
$
%t
%f
%eps
%io
%i
%e
%pi
using
14875 elements out of
1000000.
and
75 variables out of
1023
Zmienne, które zostaªy wprowadzone Anew, A,A22, A21, ...,b w porz¡dku
odwrotnym do ich wczytywania. Wªa±ciwie pierwsz¡ utworzon¡ zmienn¡
byªa macierz
A ale powi¦kszyli±my jej wymiar (z (3,3) do (4,4)) w przykªadzie
prezentuj¡cym konkatenacj¦ macierzy. W takim przypadku zmienna pocz¡tkowa
zostaje zast¡piona now¡ zmienn¡. O tym istotnym fakcie powiemy jeszcze
przy okazcji omawiania programowania w Scilab-ie;
Nazwy bibliotek Scilab-a (posiadaj¡cych rozszerzenie lib) i funkcji:
cosh.
To znaczy funkcje (te opisane w j¦zyku Scilab-a) oraz biblioteki traktowane
s¡ przez Scilaba jak zmienne.
Uwaga: Procedury w Scilabie zaprogramowane w Fortran 77 i C nazywane
s¡ prymitywami Scilaba i nie s¡ uwa»ane za zmienne w Scilabie. W
dalszej cz¦±ci tego dokumentu u»ywa si¦ czasem przesadnie sformuªowania
prymityw aby zaznaczy¢ funkcje Scilab-a (programów w j¦zyku Scilab),
które s¡ zawarte w standardowo dost¦pnym ±rodowisku.
Staªe predeniowane, takie jak
, e i i
inne staªe, klasyczne w arytmetyce zmiennoprzecinkowej:
a number,
inf
1.
Zmienne, których nazwa poprzedzona
20
eps oraz dwie
nan - ang. not
jest znakiem %
epsilon maszynowy
nie mog¡ zosta¢ usuni¦te.
Bardzo istotna zmienna
newstacksize
okre±laj¡ca rozmiar stosu (to znaczy
ilo±¢ dost¦pnej pami¦ci).
Na koniec wy±wietlona zostaje informacja o ilo±ci u»ytych sªów 8 bitowych
w odniesieniu do ich caªkowitej (dost¦pnej) ilo±ci a nast¦pnie ilo±¢ u»ytych
zmiennych w stosunku do maksymalnej dozwolonej ich ilo±ci.
Rozmiar stosu mo»na zmieni¢ za pomoc¡ polecenia
nbmots
oznacza nowy po»¡dany rozmiar.
stacksize(nbmots)
gdzie
Ta sama komenda bez argumentu
pozwala uzyska¢ rozmiar stosu mieszcz¡cy maksymaln¡ dopuszczaln¡ liczb¦
zmiennych.
Tak wi¦c chc¡c usun¡¢ wektor
pami¦ci nale»y u»y¢ polecenia
v1
ze ±rodowiska a wi¦c zwolni¢ miejsce w
clear v1.
Polecenie
clear
u»yte bez argumentu
usunie wszystkie zmienne. Chc¡c natomiast usun¡c wi¦cej ni» jedn¡ zmienn¡
mo»a poda¢ ich nazwy jako kolejne argumenty polecenia
clear v1 v2 v3.
2.5
clear,
na przykªad:
Wywoªanie pomocy z linii polece«
Pomoc mo»na otrzyma¢ wybieraj¡c przycisk
od wersji
2 :7
Help z menu okna Scilab.
Pocz¡wszy
3
strony pomocy s¡ w formacie HTML . Wpisuj¡c polecenie help
(lub klikaj¡c na przycisk
Help)
pojawi si¦ strona HTML zawieraj¡ca odno±niki
do wszystkich stron pomocy (Scilab
and Elementary functions,...).
Programming, Graphic Library, Utilities
Klikaj¡c na wybran¡ nazw¦ otrzymuje si¦ list¦
szystkich funkcji zwi¡zanych z danym tematem, do ka»dej z nich doª¡czono
krótki opis. Wybieraj¡c dan¡ funkcj¦ otrzymuje si¦ stron¦ z pytaniami dotycz¡cymi danej funkcji. Je»eli natomiast znana jest nazwa funkcji wystarczy
help nazwa_funkcji w oknie Scilaba aby wej±¢ na odpowiedn¡
Polecenie apropos sªowo_kluczowe wy±wietli wszystkie strony na których
wpisa¢ komend¦
stron¦.
pojawia si¦ sªowo_kluczowe w nazwach funkcji lub ich opisach. Przeszukiwanie
opcji mo»e okaza¢ sie niewygodne, gdy» cz¦sto wiele funkcji zgrupowanych jest
pod jedn¡ nazw¡ (na przykªad jako Elementary functions mojetutu wyst¦puje
bardzo du»o ró»nych funkcji, które w jakimkolwiek stopniu na t¦ nazw¦ zasªuguj¡); nie wahaj sie zatem u»ywa¢ polecenia
2.6
apropos
Generator prostych wykresów
Przypu±¢my, »e chcemy narysowa¢ wykres funkcji
y = e x sin(4x) dla x 2 [0; 2].
Mo»na zdeniowa¢ podziaª przedziaªu poprzez funkcj¦
linespace
-->x=linspace(0,2*%pi,101);
a nast¦pnie policzy¢ warto±ci funkcji dla ka»dego elementu podziaªu wykrzystuj¡c w tym celu instrukcj¦
-->y=exp(-x).*sin(4*x);
i ostatecznie
-->plot(x,y,'x','y','y=exp(-x)*sin(4x)')
gdzie trzy ostatnie ªa«cuchy znaków (odpowiednio: opis osi rz¦dnych i odci¦tych oraz nazwa wykresu) s¡ opcjonalne. Instrukcja ta pozwala narysowa¢
krzyw¡ przechodz¡c¡ przez punkty, których wspóªrz¦dne okre±la wektor
osi odci¦tych oraz
3
y
na osi rz¦dnych.
Format podstawowy to XML a z niego otrzymuje si¦ HTML.
21
x
na
Je»eli punkty ukªadaj¡ si¦ cz¦±ciowo
wzdªu» linii prostej wykres b¦dzie tym wierniejszy im wi¦kszej ilo±ci punktów
u»yjemy
Rysunek 2.1: Prosty wykres.
Uwaga: Ta instrukcja jest ograniczona, zatem nie nale»y sugerowa¢ si¦ jedynie
tym rozwi¡zaniem. W rozdziale dotycz¡cym graki wprowadza si¦ instrukcje
plot2d,
2.7
która jest o wiele lepsza.
Pisanie i wykonywanie skryptów
Mo»liwe jest wpisanie ci¡gu instrukcji do pliku
nazwaPliku
i ich wywoªanie
poprzez komend¦
-->exec('nazwa_pliku')
Prostsz¡ metod¡ jest
File
okna Scilab.
// lub exec nazwa_pliku
wybranie pozycji File Operation
znajduj¡c¡ si¦ w menu
Menu pozwala wybra¢ insteresuj¡cy nas plik (ewentual-
nie w celu jego modykazji); aby go wykona¢ wystarczy wybra¢
Exec.
przykªad skryptu rozwa»my ponownie wykres funkcji
zadaj¡c za
ka»dym razem inny rozmiar przedziaªu
e x sin(4x)
[a; b] i ilo±¢ podprzedzaiªów.
zatem w pliku nazywaj¡cym si¦ na przykªad
Jako
Napiszmy
script1.sce nast¦puj¡ce instrukcje
// pierwszy skrypt
a = input(" Podaj lewy kraniec przyedzialu : ");
b = input(" Podaj prawy kraniec przedzialu : ");
n = input(" Podaj ilosc podprzedzialow : ");
// obliczenie odcietych
x = linspace(a,b,n+1);
// obliczenie rzednych
y = exp(-x).*sin(4*x);
// maly rysunek
clf() //wyczyszczenie zawartosci okna graficznego
plot(x,y,"b")
xtitle("x","y","y=exp(-x)*sin(4x)")
Uwaga:
Aby odnale¹¢ si¦ w naszych plikach Scilab-a zaleca si¦ wykorzysta¢ w
*.sce (w
by¢ *.scu).
nazwie pliku skryptowego rozszerzenie
wiera funkcj¦, rozszerzeniem powinno
przypadku gdy plik za-
Pewne edytory mog¡ by¢ wyposa»one w narz¦dzia specyczne dla edycji
w Scilabie (zobacz strona Scialba). Dla
emacs
istniej¡ dwa, z krórych lep-
szy pochodzi od Alexandra Vigodnera, którego najnowsze wersje mo»na
znale¼¢ pod adresem
http://www.geocities.com/avezunchik/scilab.html
22
2.8
Dodatkowe informacje
2.8.1 Skracanie instrukcji przy zapisie macierzowym
Wcze±niej dowiedzieli±my si¦, »e mno»enie macierzy przez skalar (podobnie
dzielenie macierzy przez skalar) jest zdeniowane w Scilabie. Natomiast Scilab
stosuje uproszcze« mniej oczywistych, takich jak dodawanie skalara i macierzy.
M + s gdzie M
M + s*ones(M)
Wyra»enie
jest macierza a
s
skalarem jest skrótem dla instrukcji
to znaczy skalar jest dodany do wszystkich elementów macierzy.
Inny skrót: w wyra»eniu typu
mencie
A./B
(oznaczaj¡cym dzielenie element po ele-
macierzy o tych samych wymiarach), je»eli
A
jest skalarem wówczas
wyrarzenie to jest skróconym zapisem dla instukcji :
A*ones(B)./B
otrzymuje sie macierz
[a=bij ].
Takie uproszczenia pozwalaj¡ na zapis bardziej
f jest
x jest wektorem a s jest zmienn¡, wówczas
syntetyczny w wielu przypadkach (por. ¢wiczenia). Na przykªad, je±li
funkcj¡ zdeniowan¡ w ±rodowisku,
s./f(x)
x, w którym i-ta wspóªrz¦dna równa
wyznaczy¢ wektor o wspóªrz¦dnych 1=f (xi ),
jest wektorem tych samych wymiarów co
jest
s=f (xi ).
W ten sposób, aby
u»yjemy skªadni :
1./f(x)
Taka skªadnia interpretuje
1.
jako jedynk¦ i wynik nie b¦dzie wªa±ciwy. Do-
brym rozwi¡zaniem aby otrzyma¢ poszukiwany wynik jest uj¦cie liczby w nawias lub oddzielenie liczby spacj¡ :
(1)./f(x)
// lub takze 1 ./f(x)
lub 1.0./f(x)
2.8.2 Pozostaªe uwagi dotycz¡ce rozwi¡zywania ukªadów równa« liniowych (*)
1. W przypadku gdy mamy wi¦cej wyrazów wolnych, mo»na stosowa¢ nast¦puj¡ce polecenie :
-->y1 = [1;0;0;0]; y2 = [1;2;3;4]; // przypadek gdy mamy 2 wyrazy wolne ( mozn
-->
// wiecej instrukcji w jednej lini)
-->X=A\[y1,y2]
// konkatenacja/zlaczenie y1 i y2
X =
! 4.
- 0.8333333 !
! - 3.
1.5
!
! 1.3333333 - 0.5
!
! - 0.25
0.0833333 !
Pierwsza kolumna macierzy X jest rozwi¡zaniem ukªadu równa«
2.
natomiast druga jest rozwi¡zaniem ukªadu Ax2 = y 2 .
Wcze±niej zobaczyli±my, »e je»eli A jest macierz¡ kwadratow¡
Ax1 = y1 ,
(n,n) oraz
b
jest wektorem kolumnowym o n wspóªrz¦dnych (a wi¦c macierz¡ (n,1)) to
:
x = A\b
Ax = b. Je»eli natomiA oka»e sie macie»¡ osobliw¡, Scilab zwróci bª¡d. Na przykªad
da nam rozwi¡zanie ukªadu równa« liniowych postaci
ast macierz
:
-->A=[1 2;1 2];
23
-->b=[1;1];
-->A\b
!--error
19
singular matrix
Podczas gdy macierz
A jest ¹le uwarunkowana (lub ewentualnie ¹le zrównowa»ona)
odpowied¹ b¦dzie dostarczona ale wraz z komentarzem w postaci ostrze»enia zawieraj¡cym oszacowanie odwrotno±ci uwarunkowania (cond(A)
-->A=[1 2;1 2+3*%eps];
-->A\b
warning
matrix is close to singular or badly scaled.
results may be inaccurate. rcond = 7.4015D-17
!
!
= jjAjj jjA 1 jj):
ans =
1. !
0. !
Z drugiej strony, je»eli macierz nie jest kwadratowa, ale posiada t¦ sam¡
liczb¦ wirszy co wektor wyrazów wolnych, Scilab obliczy rozwi¡zanie (w
postaci wektora kolumnowego, którego liczba wspóªrz¦dnych b¦dzie równa
liczbie kolumn macierzy
A) nie informuj¡c u»ytkownika o bª¦dzie.
W efek-
cie, je»eli równanie Ax = b nie ma w ogólno±ci rozwi¡zania jednoznacznego
4 , mo»na zawsze wybra¢ wektor x który zwerykuje pewne wªasno±ci (x
o minimalne normie i jednocze±nie b¦d¡cy rozwi¡zaniem
min jjAx
bjj).
W tym przypadku takie rozwi¡zanie jest wynikiem dzieªanie innych algorytmów które umo»liwiaj¡ (ewentualne) otrzymanie pseªdo-rozwi¡zania5 .
Niedogodno±¢ jest taka, »e jes±li zostanie popeªniony bª¡d podczas deniowania macierzy (na przykªad zdeniowana zaostanie dodatkowa kolumna
tak, »e macierz b¦dzie miaªa wymiar (n,n+1)) bª¡d ten nie zostanie wykryty
natychmiast. Rozwa»my przykªad :
-->A(2,3)=1
A =
! 1. 2. 0. !
! 1. 2. 1. !
// étourderie
-->A\b
ans =
! 0.
!
! 0.5
!
! - 3.140D-16 !
-->A*ans - b
ans =
1.0D-15 *
! - 0.1110223 !
4
A (gdzie n =
6 m), mamy jedno rozwi¡zanie wtedy i tylko wtedy, gdy m > n,
f0g i w konsekwencji b 2 ImA ten ostatni warunek jest wyj¡tkiem je±li b jest zadane z góry w Km ; w ka»dym
niech (m; n) b¦dzie wymiarem macierzy
KerA =
innym przypadku albo nie ma »adnego rozwi¡zania albo isnieje niesko«czenie wiele rozwi¡za«
5
w przypadkach trudnych, tzn. takich, gdzie macierz nie ma maksymalnego rz¦du (rg (A)
dwuwymiarowe) nale»y wyznaczy¢ rozwi¡zanie korzystaj¡c z pseªdo-odwrotnej macierzy do
24
< min(n; m) gdzie n i m s¡
A (x = pinv(A)*b).
! - 0.1110223 !
Poza zwróceniem naszej uwagi na konsekwencje tego typu zakªuce«, powy»szy
przykªad ilustruje nast¦puj¡ce aspekty :
x = A\y pozwala rozwi¡za¢ problem mniej kwadratowy (kiedy macierz nie
ma maksymalnego rz¦du, nale»y lepiej u»y¢/wyko»ysta¢ x = pinv(A)*b,
pseudo-inwersia zostanie obliczona poprzez dekompozycj¦ pojedynczych
warto±ci
A (t¦ dekompozycj¦ mo»na otrzyma¢ za pomoc¡ instukcji svd));
instrukcja
A(2,3)=1
(bª¡d zakªucenia. . . ) jest w rzeczywisto±ci skrótem
od :
A = [A,[0;1]]
A
to znaczy Scilab domy±la si¦, »e macierz
ma by¢ uzupeªniona (o 3
kolumn¦) ale brakuje mu jednego elementu. W takim przypadku uzupeªni je zerami.
element na pozycji (2,2) jest równy
2+3 m .
Epsilon maszynowy (m ) ma»e
by¢ zdeniowany jako bardzo du»a liczba, dla której 1
m = 1 w arytmetyce zmiennoprzecinkowej6 . W konsekwencji musimy mie¢ 2 3m > 2
aby na ekranie pojawiªa si¦
2.
Wynika to z u»ytego domy±lnie formatu
danych, mo»na go jednak zmodykawa¢ u»ywaj¡c instrukcji
format
:
-->format('v',19)
-->A(2,2)
ans =
2.0000000000000009
W ten sposób zmienimy format domy±lny
format('v',10)
(patrz
Help
aby
pozna¢ znaczenie argumentów).
Rozwi¡zanie ukªadu
Ax = b, które nie zostaªo przypisane »adnej konkret-
niej zmniennej, jest domy±lnie nazwane
ans.
Zmienn¡ t¦ mo»na nast¦pnie
wyko»ysta¢ do obliczenia warto±ci rezydualnej
Ax b.
3. Przy u»yciu Scilaba mo»na równie» odpowiednio rozwi¡za¢ ukªad równa«
postaci
xA = b
gdzie
x
i
b
s¡ wektorami wierszowymi, a
A
jest macierz¡
kwadratow¡ (poprzez transpozycj¦ wracamy do ukªadu klasycznego
b> ),
wystarczy pomno»y¢ prawostronnie przez
A 1
operacji jest prawostronne podzielenie przez macierz
x = b/A
I podobnie jak poprzednio, je±li
A
A> x> =
(odpowiednikiem tej
A) :
jest macierz¡ prostok¡tn¡ (gdzie liczba
kolumn jest równa liczbie wierszy wektora b), Scilab wyznaczy rozwi¡zanie.
2.8.3 Kilka prostych macierzy (*)
Suma, iloczym wspóªczynników macierzy, macierz pusta
sum :
// 1:6 = [1 2 3 4 5 6] : musiemy zatem otrzymac 6*7/2 = 21 !!!!!
Aby zsymowa¢ wspóªczynniki macierzy, u»ywamy funkcji
-->sum(1:6)
ans =
21.
Funckja ta przyjmuje przyjmuje argument dodatkowy dla obliczenia tylko
wierszy lub tylko kolumn :
6
±ci±le mówi¡c wszystkie liczby rzeczywiste
zmiennoprzecinkowej
j
f l(x) nast¦puj¡co : x
j j
x takie, »e m
x
M mog¡ by¢ zakodowane/zapisane za pomoc¡ liczby
f l(x)
m x gdzie m i M s¡ odpowiednio najmniejsz¡ i najwi¦ksz¡ liczb¡
j j j
dodatni¡ mo»liw¡ do zakodowania za pomoc¡ virgule ottante normalisée
25
-->B = [1 2 3; 4 5 6]
B =
! 1.
2.
3. !
! 4.
5.
6. !
-->sum(B,"r") // oblicza sume wyrazów w poszczegolnych kolumnach
//otrzymujemy wektor wierszowy postaci
ans =
! 5.
7.
9. !
-->sum(B,"c") // oblicza sume wyrazow w poszczegolnych wierszach
// otrzymujemy wektor kolumnowy postaci
ans =
! 6. !
! 15. !
Jednym z wyj¡tkowo u»ytecznych obiektów jest macierz pusta któr¡ deniuje
sie nast¦puj¡co :
-->C =[]
C =
[]
Macierz ta ma nast¦puj¡ce wªasno±ci :[]
sum
-->sum([])
ans =
0.
funkcj¦
+ A = A
i
[]*A = [].
Stosuj¡c teraz
do macierzy pustej otrzymujemy naturalnie rezultat :
wedªug matematycznej konwencji sumowania :
S=
je»eli
E
X
i2E
ui =
n
X
i=1
ui
jest zbiorem pustym wówczas
gdy
E = f1 ; 2 ; : : : ; n g
S = 0 W analogiczny sposób, aby otrzy-
ma¢ iloczyn elementów macierzy, stosuje sie funkcj¦
-->prod(1:5)
ans =
120.
// otrzymujemy 5! = 120
-->prod(B,"r") // napisz B aby zobczyc macierz...
ans =
! 4.
10.
18. !
-->prod(B,"c")
ans =
! 6. !
! 120. !
-->prod(B)
ans =
720.
-->prod([])
ans =
26
prod
:
1.
wynik otrzymuje si± zgodnie z konwencj¡ znan¡ w matematyce :
Y
i2E
ui = 1;
si
E = ;:
Suma i iloczyn skumulowany
Funkcje
cumsum
i
cumprod
obliczaj¡ odpowiednio sum¦ i iloczyn skumiulowany
macierzy lub wektora :
-->x = 1:6
x =
! 1.
2.
3.
4.
-->cumsum(x)
ans =
! 1.
3.
6.
10.
15.
-->cumprod(x)
ans =
! 1.
2.
6.
24.
120.
5.
6. !
21. !
720. !
Dla macierzy kumulowanie dokonuje si± zazwyczja jedynie w porz¡dku kolumnowym :
-->x = [1 2 3;4 5 6]
x =
! 1.
2.
3. !
! 4.
5.
6. !
-->cumsum(x)
ans =
! 1.
7.
! 5.
12.
15. !
21. !
Podobnie jak w przypadku funkcji
sum
i
prod,
mo»na dokonywa¢ kumulowania
wedªug wierszy i kolumn :
-->cumsum(x,"r") // suma skumulowana wedlug kolumn !
ans =
! 1.
2.
3. !
! 5.
7.
9. !
-->cumsum(x,"c") // suma skumulowana wedlug wierszy !
ans =
! 1.
3.
6. !
! 4.
9.
15. !
Pojawia si¦ tutaj pozorna niezgodno±¢ pomi¦dzy nazw¡ a sposobem dokonywania oblicze« na wierszach i kolumnach7 : dla funkcji sum i prod argument
informuje o ostatecznej formie otrzymanego wyniku (sum(x,»") pozwala otrzy-
ma¢ wektor wierszowy (r jak row, ang. wiersz) a wi¦c sum¦ ka»dej kolumny)
lecz
7
sum, prod, cumsum, cumprod, mean, st_deviation, min, max
27
minimum i maksimum wektora i macierzy
Najmniejsz¡ i najwi¦ksz¡ warto±¢ wektora lub macierzy mo»na wyznaczy¢
posªuguj¡c si¦ funkjami
funkcji
sum
i
prod
min
i
max.
Ich dziaªanie jest takie jak w przypadku
gdzie dodatkowy argument okre±la czy minimum lub mak-
simum ma by¢ wyznaczone dla wiersza czy dla kolumny. Dodatkowo mo»liwe
jest znalezienie wska¹nika dla miejsca w któtym znajduje sie owo minimum
lub maksimum. Przykªady :
-->x = rand(1,5)
x =
! 0.7738714
0.7888738
0.3247241
0.4342711
0.2505764 !
-->min(x)
ans =
0.2505764
-->[xmin, imin] = min(x)
imin =
5.
// min jest osiagniete w x(5)
xmin =
0.2505764
-->y = rand(2,3)
y =
! 0.1493971
0.475374
! 0.1849924
0.1413027
0.8269121 !
0.7530783 !
-->[ymin, imin] = min(y)
imin =
! 2.
2. !
// min jest osiagniete dla y(2,2)
ymin =
0.1413027
-->[ymin, imin] = min(y,"r") // minimum kazdej kolumny
imin =
! 1.
2.
2. !
// => min to y(1,1) y(2,2) y(2,3)
ymin =
! 0.1493971
0.1413027
0.7530783 !
-->[ymin, imin] = min(y,"c") // minimum kazdego wiersza
imin =
! 1. !
// min to y(1,1)
! 2. !
//
y(2,2)
ymin =
! 0.1493971 !
! 0.1413027 !
±rednia i odchylenie standardowe
Funkcje
mean i st_deviation
pozwalaj¡ wyznaczy¢ ±redni¡ i odchylenie standar-
dowe wspóªrz¦dnych wektora lub macierzy. Formuªa u»ywana dla odchylenia
28
standardowego jest nast¦puj¡ca :
-->x = 1:6
x =
! 1.
2.
n
1 X
(x) =
(x
n 1 i=1 i
3.
4.
5.
x)2
!1=2
; x =
n
1X
x
n i=1 i
6. !
-->mean(x)
ans =
3.5
-->st_deviation(x)
ans =
1.8708287
Podobnie mo»na wyznaczy¢ ±redni¡ (a tak»e odchylenie standardowe) wiersza
lub kolumny macierzy :
-->x = [1 2 3;4 5 6]
x =
! 1.
2.
3. !
! 4.
5.
6. !
-->mean(x,"r")
ans =
!
2.5
3.5
-->mean(x,"c")
ans =
!
!
// srednia wyrazow kazdej z kolumn macierzy
4.5 !
// srednia kazdego z wierszy
2. !
5. !
Przeksztaªcenie macierzy
Funkcja
matrix
umo»liwia takie przeksztaªcenie macierzy aby miaªa ona nowe
wymiary (przy zachowaniu tych samych wspóªczynników).
-->B = [1 2 3; 4 5 6]
B =
! 1.
2.
3. !
! 4.
5.
6. !
-->B_new = matrix(B,3,2)
B_new =
! 1.
5. !
! 4.
3. !
! 2.
6. !
Jest to mo»liwe dzi¦ki temu, »e wspóªczynniki macierzy zapami¦tywane s¡
kolumnowo. Jednym z zastowowa« funkcji
wierszowego na kolumnowy i odwrotnie.
29
v
:
jest transpozycja wektora
A zamieniaj¡c (wektory
v = A(:), przykªad :
pozwala ona tak»e przeksztaªci¢ macierz
kolumnowe) na wektor kolumnowy
matrix
Nale»y zaznaczy¢, »e w ogólno±ci
wierszowe i
-->A = rand(2,2)
A =
! 0.8782165
0.5608486 !
! 0.0683740
0.6623569 !
-->v=A(:)
v =
! 0.8782165
! 0.0683740
! 0.5608486
! 0.6623569
!
!
!
!
Wektory z post¦pem logarytmicznym
Czasami istnieje potrzeba operownia wektorem którego wspóªrz¦dne stanowi¡
post¦p logarytmiczny (tzn.
:xi
+1 =xi = Cte):
takie, »e stosunek dwuch s¡siednichc jest staªy
mo»na u»y¢ w tym przypadku funkcj¦
logspace : logspace(a,b,n):
n wspóªrz¦dnych w którym pierwsza i os10a i 10b , np:
pozwalaj¡c¡ otrzyma¢ taki wektor o
tatnia wsóªrz¦dna s¡ odpowiednio
-->logspace(-2,5,8)
ans =
! 0.01
0.1
1.
10.
100.
1000.
10000.
100000. !
Warto±ci i wektory wªasne
spec pozwala obliczy¢
-->A = rand(5,5)
A =
! 0.2113249
0.6283918
! 0.7560439
0.8497452
! 0.0002211
0.6857310
! 0.3303271
0.8782165
! 0.6653811
0.0683740
Funkcja
warto±ci wªasne macierzy (kwadratowej!) :
0.5608486
0.6623569
0.7263507
0.1985144
0.5442573
0.2320748
0.2312237
0.2164633
0.8833888
0.6525135
0.3076091
0.9329616
0.2146008
0.312642
0.3616361
!
!
!
!
!
-->spec(A)
ans =
! 2.4777836
!
! - 0.0245759 + 0.5208514i !
! - 0.0245759 - 0.5208514i !
! 0.0696540
!
! 0.5341598
!
oraz wy±wietla wyniki w postaci wektora kolumnowego (Scilab stosuje metod¦
QR polegaj¡c¡ na interacyjnej dekompozycji) Schur macierzy). Wektory wªasne
mog¡ by¢ otrzymane za pomoc¡
bdiag. W
gspec.
ogólno±ci aby wyznaczy¢ warto±ci
wªasne mo»na wyko»ysta¢ funkcj¦
2.8.4 Funkcje size i length
size
pozwala uzyska¢ informacj¦ o wymiarach macierzy (w kolejno±ci: liczba
wierszy, liczba kolumn):
-->[nl,nc]=size(B)
nc =
3.
// B jest macierz\k{a} (2,3) z poprzedniego przyk\l{}adu
30
nl =
2.
-->x=5:-1:1
x =
! 5.
4.
3.
-->size(x)
ans =
! 1.
5. !
natomiast length
2.
1. !
mówi o liczbie elementów macierzy (rzeczywistych lub ze-
spolonych). W ten sposób dla wektora wierszowego lub kolumnowego otrzymuje si¦ dokªadnie liczb¦ jego wspóªczynników :
-->length(x)
ans =
5.
-->length(B)
ans =
6.
Obie te instrukcje u»ywane s¡ po to aby pozna¢ rozmiar macierzy lub wek-
size(A,'r') (lub
size(A,1)) oraz size(A,'c') (lub size(A,2)) mówi¡ o liczbie wierszy (rows) oraz
tora b¦d¡cego argumentem tych funkcji. Nale»y doda¢, »e
kolumn (columns) macierzy
2.9
A.
‚wiczenia
1. Zdeniowa¢ macierz wymiaru
diag
funkcji
za pomoc¡
Help):
n
0
2
B
B
1
B
B
A=B 0
B
B
@ ..
.
0
nast¦puj¡co (zob.
1
1
.. C
. C
C
C
0 C
C
C
A
0
0
..
.
..
.
..
.
..
.
..
.
..
.
..
.
..
.
..
.
0
szczegóªy dotycz¡ce
1
1
2
A b¦dzie macierz¡ kwadratow¡; czym b¦dzie diag(diag(A)) ?
2. Niech
3. Funkcja
tril
pozwala wydoby¢ trók¡tn¡ doln¡ cz¦±¢ macierzy (triu dla
cz¦±ci trójk¡tnej górnej). Zdeniowa¢ dowoln¡ macierz kwadratow¡
za pomoc¡
górn¡
T
rand)
tak¡, »e
A (np.
i skonstruowa¢ pojedyncz¡ instrukcj¡ macierz trójk¡tn¡
tij = aij dla i > j (cz¦±ci trójk¡tne górne macierzy A i T
tii = 1 (T jest diagonalnie jednostkowa).
s¡
jednakowe) i tak¡, »e
4. Niech
X
b¦dzie macierz¡ (lub wektorem) zdeniowanym w ±rodowisku.
Napisa¢ instrukcj¦ pozwalaj¡c¡ obliczy¢ macierz
aru co
X)
w której element na pozycji
nast¦puj¡cych przypadkach :
(a)
(b)
(c)
(d)
f (x) = 2x2 3x + 1
f (x) = j2x2 3x + 1j
f (x) = (x 1)(x + 4)
f (x) = 1+1x2
31
(i; j )
Y
(tego zamego rozmi-
jest równy warto±ci
f (Xij )
w
5. Naszkicowa¢ wykres funkcji
f (x) = sinx x
dla
x 2 [0; 4] (napisa¢ skrypt).
6. Maªa ilustracja prawa wielkich liczb : obliczy¢ za pomoc¡ funkcji
realizacji rozkªadu zero-jednkowego w postaci wektora
P
xk = k1 ki=1 xi
skumulowan¡ tego wektora, tzn. wektor
nych ma warto±¢ :
x,
x,
rand
obliczy¢ ±redni¡
którego ka»da z
n
wspóªrz¦d-
oraz naszkicowa¢ wykres ci¡gu otrzy-
manego w ten sposób. Zbada¢ jego zachowanie, zwi¦kszaj¡c warto±¢
32
n
n.
Rozdziaª 3
Programowanie w Scilabie
Scilab, oprócz prostych instrukcji (pozwalaj¡cych, z wyko»ystaniem instrukcji
macierzowych, na bardzo syntetyczne programowanie bliskie j¦zykowi matematycznemu, co najmniej macierzowemu) dysponuje prostym aczkolwiek wystarczaj¡co kompletnym j¦zykiem programowania. Zasadnicz¡ ró»nic¡ w porównaniu z najpopularniejszymi dzi± j¦zykami (C, C++, Pascal, . . . ) jest brak
konieczno±ci deklarowania zmiennych: w przeciwie«stwie do operacji wcze±niej
wykonywanych, nie musimy w »adnym momencie precyzowa¢ rozmiaru macierzy
ani jej typu (rzeczywista, zespolona, . . . ). To na interpreterze Scilaba spoczywa
zadanie rozpoznawania ka»dego nowego obiektu. Takie podej±cie nie jest cz¦sto
brane pod uwag¦, gdy» z punktu widzenia programisty prowadzi¢ mo»e do
powstawania trudnych do wychwycenia bª¦dów. W przypadku j¦zyków takich
jak Scilab (czy MATLAB) nie powoduje to problemów dzi¦ki u»ywaniu zapisu wektorowego/macierzowego oraz gotowych prostych instrukcji, pozwalaj¡cych na znaczne zmniejszenie ilo±ci zmiennych oraz wielko±ci kodu (tutu na
przykªad instrukcje macierzowe pozwalaj¡ce unikn¡¢ maksimum p¦tli ). Inn¡
zalet¡ j¦zyków programowania tego typu jest to, »e dysponoj¡ one instrukcjami gracznymi (co pozwala unikn¡¢ »onglowania programem lub bibliotek¡
graczn¡) i s¡ one interpretowane (co umo»liwia ªatwe odnalezieniebª¦dów bez
pomocy debugera). Dla odmiany niedogodnym jest, »e programy napisane w
Scilabie s¡ wolniejsze od tych napisanych w C (ale program w C wymaga 50
razy wi¦cej czasu na napisanie i dopracowanie). Z drugiej strony, w aplikacjach gdzie ilo±¢ zmiennych jest szczególnie istotna (na przykªad macierz 1000
x 1000) lepiej powróci¢ do j¦zyka kompilowanego. Istotnym punktem wpªywaj¡cym na szybko±¢ wykonania jest konieczno±¢ stosowania maksymalnie cz¦sto
instrukcji prostych i instrukcji macierzowych (oznacza to ograniczenie do minimum ilo±ci p¦tli)1 . W efekcie Scilab odwoªuje si¦ tak»e do skompilowanych
funkcji (fortran) dzi¦ki czemu interpreter ma mniej pracy (pracuje mniej). Dla
wykorzystania najlepszego z tych dwóch modeli (to znaczy szybko±ci j¦zyka
kompilowanego i wygody ±rodowiska takiego jak Scilab), u»ytkownik ma mo»liwo±¢ wywoªywania podprogramów w fortranie(77) lub C.
3.1
P¦tle
W Scilabie mamy mo»liwo±¢ u»ycia jednej z dwóch petli:
1
patrz równie»: sekcja Kilka uwag dotycz¡cych szybko±ci
33
for
oraz
while.
3.1.1 P¦tla for
P¦tla
for
sªu»y do powtarzania pewnego ci¡gu instrukcji; zmienna staruj¡ca
p¦tli przyjmuje kolejne warto±ci wektora liniowego
-->v=[1 -1 1 -1]
-->y=0; for k=v, y=y+k, end
Ilo±¢ iteracji (powtórze«) okre±lona jest przez ilo±¢ skªadników wektora; w itej iteracji warto±¢
k
jest równa
nast¦puj¡co
dla
i := istart
a» do
instrukcje
iend
v(i).
z krokiem
Opisowo p¦tle
istep
for
przedstwi¢ mo»na
powtarzaj :
koniec powtarzaj
Jako wektora mo»na u»y¢ wyra»enia
i_start:i_step:i_end;
je±li przyrost
iStep
ma warto±¢ 1 to jak widzieli±my wcze±niej mo»e zosta¢ pomini¦ty. Przedstawiona wcze±niej jako przykªad p¦tla
for
mo»e zosta¢ tak»e napisana w bardziej
naturalny sposób
-->y=0; for i=1:4, y=y+v(i), end
Kilka uwag:
Zmienna steruj¡ca mo»e tak»e przyjmowa¢ warto±ci pochodz¡ce z macierzy.
W takim przypadku ilo±¢ iteracji równa jest ilo±ci kolumn macierzy, a zmienna steruj¡ca w i-tym przebiegu p¦tli jest równa i-tej kolumnie macierzy
-->A=rand(3,3);y=zeros(3,1); for k=A, y = y + k, end
Dokªadna skªadnia instrukcji for wygl¡da nast¦puj¡co
for zmienna = macierz, ciag instrukcji, end
gdzie instrukcje oddzielone s¡ od siebie przecinkiem (lub ±rednikiem je±li
nie chcemy widzie¢ na ekranie rezultatów wykonania instrukcji). Poniewa»
lista zmiennych rozdzielonych przecinkiem równowa»na jest takiej samej
li±cie rozdzielonej spacjami, dlatego w skryptach lub funkcjach cz¦±ciej stosuje si¦ wygodniejszy (bardziej czytelny) zapis:
for zmienna = macierz
instrukcja1
instrukcja2
...........
instrukcjan
end
gdzie instrukcja mo»e ko«czy¢ si¦ ±rednikiem (b¦dzie tak zawsze jesli chcemy
unikn¡¢ pojawiania si¦ rezultaów instrukcji na ekranie)2 .
3.1.2 P¦tla while
P¦tla
while pozwala na powtarzanie ci¡gu instrukcji tak dªugo dopóki prawdziwy
jest pewnien warunek:
-->x=1 ; while x<14,x=2*x, end
Zadaj¡c warunek mo»emy wykorzysta¢ nast¦puj¡ce operatory porównania:
==
~=
2
<
>
<=
>=
lub
równe
mniejsze
wi¦ksze
mniejsze lub równe
<>
wi¦ksze lub równe
ró»ne
dziaªa to jedynie dla skryptów poniewa» w funkcji, wynik dowolnej instrukcji nie jest wy±wietlany nawet je±li nie jest
ono zako«czona ±rednikiem ; to (domy±lne) zachowanie mo»na zmodykowa¢ za pomoc¡ instrukcji
34
mode
Scilab posiada wbudowany typ logiczny, w którym dla oznaczenia prawdy stosuje si¦ symbole
%t
lub
%T
za± faªszu
%f
lub
%F.
Mo»na oczywi±cie zdeniowa¢
macierz lub wektor zªo»ony z warto±ci logicznych. Dost¦pne s¡ nast¦puj¡ce
operatory logiczne :
&
|
~
et
ou
non
while przedstawia si¦ jak poni»ej
while warunek, instrukcja_1, ... ,instrukcja_N , end
Formalna skªadnia p¦tli
lub (cz¦sto w przypadku skryptu lub funkcji):
while warunek
instrukcja_1
.............
instrukcja_N
end
gdzie ka»da instrukcja_k
mo»e zosta¢ zako«czona ±rednikiem,
warunek
za± jest
wyra»eniem zwracaj¡cym warto±¢ logiczn¡.
3.2
Instrukcja warunkowa
S¡ dwie instrukcje steruj¡ce przebiegiem wykonania programu: if-then-else
oraz select-case.
3.2.1 Instrukcja if-then-else
Spójrzmy na przykªad poni»ej :
-->if x>0 then, y=-x,else,y=x,end
// zmienna x powinna zostac wczesniej zdefini
Podobnie jak to miaªo miejsce dla instrukcji p¦tli przecinki nie s¡ znakami
obowi¡zkowymi.
Jak w wi¦kszo±ci spotykaych j¦zyków programowania, w
przypadku gdy nie podejmujemy »adnego dziaªania zwi¡zanego z niespeªnieniem warunku, mo»emy cz¦±¢
else
zawiera¢ by miaªa kolejn¡ instrukcj¦
elseif co prowadzi do
if warunek1 then
ciag instrukcji wykonywanych
gdy spelniony jest warunek1
elseif warunek2 then
ciag instrukcji wykonywanych
gdy spelniony jest warunek2
mo»na u»y¢
...
elseif warunekN then
ciag instrukcji wykonywanych
gdy spelniony jest warunekN
else
ciag instrukcji wykonywanych
gdy nie jest spelniony zaden
z warunków od 1 do N
end
35
pomina¢.
W przypadku gdy cz¦±¢
if-then-else
zamiast ciagu
else
ogólnego schematu tej instrukcji
else
if
oraz
Podobnie jak dla instrukcji
while warunek jest wyra»eniem zwracaj¡cym warto±¢
logiczn¡.
3.2.2 Instrukcja select-case (*)
Spójrzmy na przykªad poni»ej (prosz¦ sprawdzi¢ jego dziaªanie dla ró»nych
warto±ci zmiennej num)3
-->num = 1, select num, case 1, y = 'przypadek 1', case 2, y = 'przypadek 2',...
-->else, y = 'inne przypadki
', end
który w skrypcie lub funkcji przyjmie raczej posta¢
// zakladamy, ze zmienna num zostala dobrze okreslona
select num
case 1 y = 'przypadek 1'
case 2 y = 'przypadek 2'
else y = 'inne przypadki'
end
Scilab sukcesywnie porównuje warto±¢ zmiennej num z mo»liwymi
przypadków (1, potem 2).
pocz¡wszy od
case
warto±ciam
Je±li zajdzie równo±¢, wykonywane s¡ instrukcj¦
równego zmiennej
num
a» do ko«ca instrukcji
Przekazanie sterowania do nieobowi¡zkowej gaª¦¹i
else
gdy nie powiod¡ si¦ wszystkie wcze±niejsze testy.
select-case.
ma miejsce w sytuacji
Formalnie instrukcja ta
przedstawia si¦ nast¦puj¡co
select zmienna_testjaca
case wyrazenie_1
ciag instrukcji wykonywany gdy
zmienna_testujaca równa jest wyrazeniu_1
...
case wyrazenieN
ciag instrukcji wykonywany gdy
zmienna_testujaca rowna jest wyrazeniu_N
else
ciag instrukcji wykonywany gdy
zmienna_testujaca nie jest równa zadnemu
z wyrazen od 1 do N
end
gdzie wyrazenie_i jest wyra»eniem zwracaj¡cym warto±¢, która mo»e zosta¢
porównana ze zmienna_testujaca. Konstrukcja select-case równowa»na jest
nast¦puj¡cej konstrukcji if-then-else
if zmienna_testujaca == wyrazenie_1 then
ciag instrukcji wykonywany gdy
zmienna_testujaca rowna jest wyrazeniu_1
...
elseif zmienna_testujaca = wyrazenie_N then
ciag instrukcji wykonywany gdy
zmienna_testujaca rowna jest wyrazeniu_N
else
ciag instrukcji wykonywany gdy
3
Zmienna
y
jest ªa«cuchem znaków patrz kolejny rozdziaª.
36
nie jest spelniony zaden z powyzszych
warunków
end
3.3
Inne rodzaje zmiennych
Do tej pory u»ywali±my zmiennych b¦d¡cych macierzami (wektorami, skalarami)
zªo»onymi z warto±ci typu rzeczywistego, zespolonego lub logicznego. Oprócz
nich mamy równie» do dyspozycji zmienne reprezentuj¡ce ªa«cuchy znaków
oraz listy.
3.3.1 Ša«cuchy znaków
W przykªadzie dotycz¡cym konstrukcji select-case zmienna y jest typu ªa«cuch
znaków. W Scilabie ªa«cuchy znaków ograniczane s¡ za pomoc¡ znaku apostrofu lub cudzysªowu (je±li chcemy który± z tych znaków wykorzysta¢ w takim
ªa«cuchu, to nale»y napisa¢ go dwukrotnie). Aby przypisa¢ zmiennej
czy_to_prawda
warto±¢
Czy Scilab jest "cool" ?
nale»y napisa¢
-->czy_to_prawda = "Czy Scilab jest ""cool"" ?"
lub równowa»nie
-->czy_to_prawda = 'Czy Scilab jest ""cool"" ?'
Mo»na tak»e zdeniowa¢ macierz zªo»on¡ z ªa«cuchów znaków
-->M = ["a" "bc" "def"]
M =
!a bc def !
-->size(M) // w celu otrzymania wymiarów skladowych
ans =
! 1.
3. !
-->length(M)
ans =
! 1.
2.
3. !
Zauwa»my, »e w tym przypadku
length
nie zachowuje si¦ tak samo jak dla
macierzy liczbowej. Zwraca bowiem jako wynik macierz o takim samym wymiarze jak
M, w której wspóªczynnik okre±lony przez wspóªrz¦dne (i; j ) równy jest
co do warto±ci ilo±ci znaków w ªa«cuchu na pozycji
(i; j ).
Do ª¡czenia (konkatenacji) ªa«cuchów u»ywamy operatora
+
-->s1 = 'abc'; s2 = 'def'; s = s1 + s2
s =
abcdef
podci¡g wydobywamy za± (operacja extrakcja) przy pomocy funkcji
-->part(s,3)
ans =
c
-->part(s,3:4)
ans =
cd
37
part
Drugim argumentem funkcji
part jest wektor okre±laj¡cy indeksy znaków jakie
mamy wydoby¢ z ªa«cucha.
3.3.2 Listy (*)
Lista jest uporz¡dkowanym zbiorem obiektów Scilaba (macierzy i skalarów
rzeczywistych, zespolonych czy te» zªo»onych z ª¡«cuchów znaków, warto±ci
logicznych, funkcji, list, . . . ; ka»demu elementowi przypisuje si¦ numer). Dost¦pne
s¡ dwa rodzaje list: zwykªe i typowane. Oto przykªad listy zwykªej :
-->L=list(rand(2,2),["To jest jekis" " lancuch..."],[%t ; %f])
L =
L(1)
!
!
0.2113249
0.7560439
0.0002211 !
0.3303271 !
L(2)
!To jest jakis
lancuch...
!
L(3)
! T !
! F !
W ten oto sposób zdeniowali±my list¦, w której pierwszy element jest macierz¡
o wymiarze
(2; 2),
drugi wektorem ªa«cuchów znakowych a trzeci wektorem o
skªadnikach logicznych. Oto kilka podstawowych operacji na listach
-->M = L(1)
M =
!
!
// extrakcja (wydobycie) pierwszego skladnika
0.2113249
0.7560439
0.0002211 !
0.3303271 !
-->L(1)(2,2) = 100;
// modyfikowanie pierwszego skladnika
-->L(1)
ans =
!
!
0.2113249
0.7560439
0.0002211 !
100.
!
-->L(2)(4) = " znakow !";
// modyfikacja drugiego skladnika
-->L(2)
ans =
!To jest jakis
lancuch...
znakow !
-->L(4)="Aby dodac czwarty skladnik"
38
!
L =
L(1)
!
!
0.2113249
0.7560439
0.0002211 !
100.
!
L(2)
!To jest jakis
lancuch...
znakow !
!
L(3)
! T !
! F !
L(4)
Aby dodac czwarty skladnik
-->size(L)
ans =
// ile elementow ma lista
4.
-->length(L) // idem (tutu?)
ans =
4.
-->L(2) = null()
L =
// usuniecie drugiego elementu
L(1)
!
!
0.2113249
0.7560439
0.0002211 !
100.
!
L(2)
! T !
! F !
L(3)
Aby dodac czwarty skladnik
-->Lbis=list(1,1:3)
Lbis =
// definicja innej listy
39
Lbis(1)
1.
Lbis(2)
!
1.
2.
-->L(3) = Lbis
L =
3. !
// 3 skladnik L jest teraz lista
L(1)
!
!
0.2113249
0.7560439
0.0002211 !
100.
!
L(2)
! T !
! F !
L(3)
L(3)(1)
1.
L(3)(2)
!
1.
2.
3. !
Przejd¹my do list typowanych.
W listach tego typu pierwszy element jest
ªa«cuchem okre±laj¡cym typ elementów listy (tutu co pozwala zdeniowa¢
nowy typ danych a nast¦pnie operatory dla tego typu), kolejne elementy mog¡
by¢ dowolnymi obiektami Scilaba.
Pierwszy element mo»e tak»e by¢ wek-
torem zªo»onym z ªa«cuchów znaków; pierwszy okre±la typ elementów listy,
pozostaªe za± mog¡ sªu»y¢ jako indeksy elementów listy (w miejsce ich numerów na li±cie).
Rozwa»my nast¦pujacy przykªad: chcemy reprezentowa¢
wielo±cian (w którym wszystkie ±ciany maj¡ identyczn¡ ilo±¢ kraw¦dzi).
W
tym celu przechowujemy w macierzy wspóªrz¦dne wszystkich wierzchoªków (o
wymiarze (3, ilo±¢ wierzchoªków)) do której odwoªywa¢ si¦ b¦dziemy u»ywaj¡c
ciagu coord. Nast¦pnie deniujemy macierz (o wymiarze (ilo±¢ wierzchoªków
na ±cian¦, ilo±¢ ±cian)) okre±laj¡c¡ zwi¡zek pomi¦dzy ±cian¡ a wierzchoªkami:
dla ka»dej sciany podajemy numery wierzchoªków j¡ opisuj¡cych w kolejno±ci
zgodnej z reguª¡ korkoci¡gu dla zewn¦trznego wektora normalnego.
Do tej
listy odwoªywa¢ si¦ b¦dziemy pisz¡c fence. Dla sze±cianu (porównaj rysunej
3.1) b¦dzie to wygl¡daªo jak poni»ej
P=[ 0 0 1 1 0 0 1 1;...
// wspolrzedne wierzcholkow
40
Rysunek 3.1: Numéros des sommets du cube
0 1 1 0 0 1 1 0;...
0 0 0 0 1 1 1 1];
connect = [1
2
3
4
5
8
7
6
3
7
8
4
2
6
7
3
1
5
6
2
1;... // zaleznosci pomiedzy wierzcholkami i scianami
4;...
8;...
5];
Pozostaje zdeniowa¢ list¦ typowan¡, która zawiera¢ b¦dzie wszystkie informacje o sze±cianie
-->Cube = tlist(["polyedre","coord","fence"],P,connect)
Cube =
Cube(1)
!polyedre coord
fence
!
Cube(2)
!
!
!
0.
0.
0.
0.
1.
0.
1.
1.
0.
1.
0.
0.
0.
0.
1.
0.
1.
1.
3.
7.
8.
4.
2.
6.
7.
3.
1.
5.
6.
2.
1.
4.
8.
5.
1.
1.
1.
1. !
0. !
1. !
Cube(3)
!
!
!
!
1.
2.
3.
4.
5.
8.
7.
6.
!
!
!
!
W celu wskazania pewnego elementu z wykorzystniem jego numeru, mo»na
wykorzysta¢ odpowiadaj¡cy jemy ªa«cuch znaków:
-->Cube.coord(:,2) // lub inaczej
ans =
!
!
!
Cube("coord")(:,2)
0. !
1. !
0. !
-->Cube.fence(:,1)
ans =
!
!
!
!
1.
2.
3.
4.
!
!
!
!
Pomijaj¡c te szczególne mo»liwo±ci, listami typowanymi manipuluje si¦ tak
samo jak innymi. Ich zalet¡ jest mo»liwo±¢ samodzielnego zdeniowania (i.e.
przupisania) operatorów +,
-, *, / itd.
41
na tli¢ie typu danych (porównaj przyszª¡
wersj¦ tej dokumentacji, albo dokumentacje zamieszczon¡ w sieci na domowej
stronie Scilaba.
3.3.3 Niektóre wyra»enia z wektorami i macierzami typu logiczego (boolen)
Typ boolowski (u»ywany do reprezentacji warto±ci logicznych typu prawda i
faªsz) okazuje si¦ cz¦sto przydatny ze wzgl¦dów praktycznych podczas manipuowania macierzami. Gdy porównujemy dwie macierze tego samego wymiaru za pomoc¡ jednego z operatorów porównania (<,
>, <=, >=,==, ~=)
jako
wynik otrzymujemy macierz o warto±ciach logicznych, równie» tego samego
formatu, której zawarto±¢ jest wynikiem porównania element po elemencie
odpowiadaj¡cych sobie elementów porównywanych macierzy
-->A = rand(2,3)
A =
! 0.2113249
0.0002211
! 0.7560439
0.3303271
0.6653811 !
0.6283918 !
-->B = rand(2,3)
B =
! 0.8497452
0.8782165
! 0.6857310
0.0683740
0.5608486 !
0.6623569 !
-->A < B
ans =
! T T F !
! F F T !
Je±li natomiast porównujemy macierz z liczb¡, a wi¦c
to faktycznie dokonujemy porównania
A<s*one(A)
A<s
gdzie
s
jest skalarem
-->A < 0.5
ans =
! T T F !
! F T F !
Operatory logiczne równie» stosuje si¦ dla macierzy na zasadzie element po
elemencie
-->b1 = [%t %f %t]
b1 =
! T F T !
-->b2 = [%f %f %t]
b2 =
! F F T !
-->b1 & b2
ans =
! F F T !
-->b1 | b2
ans =
! T F T !
-->~b1
ans =
42
! F T F !
Ponadto istniej¡ dwie przydatne funkcje pozwalaj¡ce dokona¢ wektoryzacji
testu
1. Funkcja
bool2s
przeksztaªca macierz boolowsk¡ w macierz o takich samych
wymiarach zamieniaj¡c warto±¢ logiczna prawda na 1, faªsz za± na 0
2.
-->bool2s(b1)
ans =
! 1.
0.
1. !
Funkcja find zwraca wspóªrz¦dne warto±ci prawda w macierzy boolowskiej
-->v = rand(1,5)
v =
! 0.5664249
0.4826472
0.3321719
0.5935095
0.5015342 !
-->find(v < 0.5)
ans =
! 2.
3. !
// v < 0.5 daje wektor boolowski
Stosowanie tych funkcji jest dosy¢ kosztowne czasowo (porównaj Kilka uwag
zwi¡zanych z szybko±ci¡ wykonania). Funkcje
and oraz or oznaczaj¡ce odpowied-
nio iloczyn logiczny (i) oraz sum¦ logiczn¡ (lub) wszystkich elementów macierzy
boolowskiej daj¡c w efekcie jedn¡ warto±¢ logiczn¡. Funkcje to mog¡ przyjmowa¢ dodatkowy argument okre±laj¡cy czy odpowiednie dziaªanie logiczne
ma zosta¢ wykonane na wierszach czy kolumnach macierzy.
3.4
Funkcje
W celu zdeniowania funkcji w Scilabie, najbardziej odpowiedni¡ metod¡ jest
zapisanie jej w utworzonym pliku; b¦dzie mo»na do niego dopisywa¢ kolejne
funkcje grupuj¡c na przykªad te zwi¡zane z tym samym czy podobnym zagadnieniem czy aplikacj¡. Ka»da funkcja powinna rozpoczyna¢ si¦ w nast¦puj¡cy
sposób
function [y1,y2,y3,...,yn]=nazwa_funkcji(x1,....,xm)
gdzie xi s¡ argumentami funkcji, natomiast yi warto±ciami przez ni¡ zwracanymi.
Dalej wyst¦puje ciaªo funkcji czyli wszystkie instrukcjie niezb¦dne do wykonania przez funkcj¦ okre±lonego zadania. Funkcja powinna ko«czyc si¦ sªowem
endfunction. Oto pierwszy przykªad
function [y] = silnia1(n)
// silnia; zakladamy, ze n jest liczba naturalna
y = prod(1:n)
endfunction
kluczowym
Zaªó»my, »e powy»sz¡ funkcj¦ zapisali±my w pliku o nazwie
silnia1.sci4 .
Aby
mo»na z niej korzysta¢ w Scilabie nale»y j¡ najpierw wczyta¢
getf("silnia1.sci")
Mo»na tego
// lub inaczej exec("silnia1.sci")
dokona¢ tak»e z menu File operations tak
jak dla skryptów.
Dopiero teraz mo»emy u»y¢ zdeniowanych w danym pliku funkcji, zarówno
w samodzielnych poleceniach jak i w skryptach czy innych funkcjach.
-->m = silnia1(5)
m =
120.
4
Tradycyjnie plik zawieraj¡cy funkcj¦ posiada rozszerznie
.sci
43
natomiast skrypt
.sce
-->n1=2; n2 =3; silnia1(n2)
ans =
6.
-->silnia1(n1*n2)
ans =
720.
Zanim przejdziemy do kolejnych przykªadów musimy ustali¢ jeszcze pewn¡ ter-
minologi¦. Argumenty wyj±ciowe (yi) oraz argumenty wej±ciowe (xi) nazywa¢
b¦dziemy argumentami formalnymi. U»ywaj¡c funkcji na przykªad w skrypcie
czy w innej funkcji
arg_s = silnia1(arg_e)
u»yte argumenty (args oraz arge )nazywabdzimyargumentamiefektywnymi:Itakwpierwszymp
Drugi przykªad pokazuje funkcj¦ znajduj¡c¡ pierwiastki trójmianu kwadratowego
function [x1,x2] = trinom(a, b, c)
// oblicza pierwiastki trojmianu kwadratowego postaci x^2 + b x + c = 0
// a, b oraz c musza byc liczbami rzeczywistymi lub zespolonymi roznymi od z
delta = b^2 - 4*a*c
x1 = (-b - sqrt(delta))/(2*a)
x2 = (-b + sqrt(delta))/(2*a)
endfunction
Oto wyniki trzech prób jej u»ycia
-->[r1, r2] = trinom(1,2,1)
r2 =
- 1.
r1 =
- 1.
-->[r1, r2] = trinom(1,0,1)
r2 =
i
r1 =
- i
-->trinom(1,0,1) // wywo\l{}anie bez tutu
ans =
- i
Zauwa»my, »e w trzecim przypadku nie widzimy drugiego z pierwiastków. Jest
to normalne zachowanie w sytuacji gdy funkcja zwraca wi¦cej ni» jedn¡ warto±¢
i nie zostan¡ one przypisane do zmiennych (tak jak ma to miejsce w drugim
przypadku). W takiej sytuacji Scilab wykorzystuje domy±ln¡ zmienn¡
przechowywa¢ wynik;
ans
ans
aby
b¦dzie przyjmowaªo kolejene zwracane warto±ci aby
ostatecznie przyj¡¢ warto±¢ równ¡ tej zwróconej jako ostaniej.
Teraz trzeci przykªad.
Nale»y rozwin¡¢ w punkcie
bazie Newtona (Uwaga: Dla
xi = 0
t
wielomian zapisany w
otrzymujemy baz¦ kanoniczn¡.)
p(t) = c1 + c2 (t x1 ) + c3 (t x1 )(t x2 ) + : : : + cn (t x1 ) : : : (t xn 1 ):
U»ywaj¡c rozkªadu na czynniki pierwsze i wykonuj¡c obliczenia od prawej do
lewej (tutaj dla
n = 4)
p(t) = c1 + (t x1 )(c2 + (t x2 )(c3 + (t x3 )(c4 )));
44
otrzymujemy algorytm Hornera
(1)
(2)
(3)
(4)
p := c4
p := c3 + (t x3 )p
p := c2 + (t x2 )p
p := c1 + (t x1 )p.
Uogólniaj¡c to na dowolne
n otrzymujemy nast¦puj¡c¡ funkcj¦ Scilaba
function [p]=myhorner(t,x,c)
// rozwija wielomian c(1) + c(2)*(t-x(1)) + c(3)*(t-x(1))*(t-x(2)) +
//
... + c(n)*(t-x(1))*...*(t-x(n-1))
// zgodnie z algorytmem Hornera
n=length(c)
p=c(n)
for k=n-1:-1:1
p=c(k)+(t-x(k))*p
end
endfunction
Je±li wektory coef, xx, tt zostaªy dobrze okre±lone instrukcja
val = myhorner(tt,xx,coef)
spowoduje przypisanie do val warto±ci równej
coef1 + coef2 (tt xx1 ) + + coefm
Maªe przypomnienie: instrukcja
mY1
i=1
(tt xxi )
length zwraca iloczyn dwóch wymiarów macierzy
daj¡c liczb¦ elementów co w przypadku wektora (kolumnowego lub wierszowego) równowa»ne jest jego dªugo±ci. Instrukcja ta, wraz z instrukcj¡
size
zwracaj¡c¡ ilo±¢ wierszy i ilo±¢ kolumn, pozwala zrezygnowa¢ z przekazywania
do funkcji informacji o wymiarze przekazywanych obiektów.
3.4.1 Przekazywanie parametrów (*)
Przekazywanie parametrów odbywa si¦ przez referencj¦ je±li parametr ten nie
jest modykowany przez funkcj¦, w przeciwnym przypadku przez warto±¢5 .
Mo»na je wyko»ysta¢ (uwzgl¦dnia¢) w celu przyspieszenia pewnych funkcji.
Poni»ej przedstawiamy sztuczny, ale dobrze ilustruj¡cy zagadnienie, przykªad
ukazuj¡cy koszt zwi¡zany z przekazywaniem parametrów przez warto±¢.
function [w] = toto(v, k)
w = 2*v(k)
endfunction
function [w] = titi(v, k)
v(k) = 2*v(k)
w = v(k)
endfunction
// skrypt testujacy
m = 200000;
il_powtorzen = 2000;
x = rand(m,1);
5
Przez warto±¢ czyli we wn¦trzu funkcji pracujemy na kopii przekazywanego argumentu.
wn¦trzu funkcji pracujemy na oryginalnym argumecie. (przyp. tªum.)
45
Przez referencj¦ czyli we
timer(); for i=1:nb_rep; y = toto(x,300); end; t1=timer()/il_powtorzen
timer(); for i=1:nb_rep; y = titi(x,300); end; t2=timer()/il_powtorzen
Otrzymane wyniki b¦d¡ ró»niªy si¦ w zale»no±ci od maszyny na jakiej dziaªa
Scilab; my otrzymali±my
t1 =
t2 =
0.00002
0.00380
Wraz z zako«czeniem funkcji destrukcji ulegaj¡ wszystkie jej zmienne wewn¦trzne.
3.4.2 Wy±wietlanie funkcji
Podczas debugowania funkcji przydatna okazuje si¦ funkcja
disp(v1, v2, ...)
v1, v2, . . . Nale»y mie¢ na uwadze,
disp wyswietla warto±ci swoich argumentów w odwrotnej kolejno±ci.
pozwalaj¡ca wy±wietli¢ warto±ci zmiennych
»e funkcja
W celu chwilowego wstrzymania wykonania programu u»y¢ mo»na funkcji
pause;
po jej napotkaniu mamy mo»liwo±¢ sprawdzenia warto±ci wszystkich
zdeniowanych do tej pory zmiennych. Polecenie
resume
powoduje wznowie-
nie przebiegu oblicze«.
Istnieje tak»e inny sposób wskazywania miejsca wstrzymania programu (tak
pause
setbpt(nazwaf unkcji[; numerl inii]) Argumentem funkcji setbpt jest nazwaf unkcji; ktrama
delbpt(nazwaf unkcji[; numerl inii]) Je±li nie zostanie wskazana »adna linia, wszystkie
zwany break point, ang.) ni» dodawanie instrukcji
punkty zatrzymania zostan¡ usuni¦te. Zdeniowane do tej pory punkty zatrzymania mo»na
zobaczyc korzystaj¡c z
trinom
dispbpt ().
Oto przykªad zwi¡zany z wcze±niej zdeniowan¡ funcj¡
(patrz strona 42). Zaªó»my, »e wczytali±my uprzednio t¡ funkcj¦ czy to za pomoc¡
funkcji
getf
czy te»
exec.
-->setbpt("trinom") // pierwszy punkt zatrzymania
-->[r1,r2] = trinom(1,2,7) // rozpoczynamy obliczenia => zatrzymanie
Stop after row
1 in function trinom :
-1->a
a =
1.
// sprawdzamy wartosci zmiennych
-1->b
b =
2.
-1->dispbpt()
// sprawdzamy punkty zatrzymania
breakpoints of function :trinom
1
-1->setbpt("trinom",5) // dodajemy kolejny punkt zatrzymania
-1->x1 // x1 nie zostal jeszcze zdefiniowany
x1
!--error
4
undefined variable : x1
-1->resume
// wznawiamy wykonanie az do nastepnego punktu zatrzymania
Stop after row
5 in function trinom :
-1->x1
// teraz mozemy sprawdzic jaka wartosc ma x1
x1 =
- 1. - 2.4494897i
-1->x2
// x2 nie zostal jeszcze zdefiniowany (nastapi to dopiero w linii 6)
46
x2
!--error
4
undefined variable : x2
-1->dispbpt()
// sprawdzamy punkty zatrzymania
breakpoints of function :trinom
1
5
-1->resume
// wznawiamy wykonanie funkcji
r2 =
- 1. + 2.4494897i
r1 =
- 1. - 2.4494897i
-->delbpt("trinom") // usuwamy wszystkie punkty zatrzymania
47
3.4.3 Instrukcja break
Instrukcja
break
pozwala przerwa¢ obliczenia wewn¡trz p¦tli
for
lub
while
i przekaza¢
sterowanie przebiegiem wykonanie do pierwszej instrukcji wyst¦puj¡cej po p¦tli.
Wykorzysta¢ j¡ mo»na do zasymulowania niedost¦pnej standardowo a znanej cho¢by z
Pascala p¦tli
repeat-until
czy odpowiadaj¡cej jej w j¦zyku C p¦tli
do-while
czy te»
przerwania oblicze« w sytuacji gdy nie ma mo»liwo±ci ich dalszego kontynowania (na
przykªad zerowy pierwszy elemnent na przk¡tnej w metodzie Gaussa). Zaªó»my, »e chcemy
mie¢ p¦tle, w której warunek wyj±cia testowany jest na ko«cu
powtarzaj
ciag instrukcji
dopoki spelniony jest warunek
W Scilabie mo»na zrealizowa¢ to w nast¦puj¡cy sposób
while %t
// poczatek petli
ciag instrukcji
if warunek then, break, end
end
S¡ sytuacje gdy u»ycie instrukcji
break
jest bardzo naturalne i prowadzi do czytelnych i
zwartych rozwi¡za«. Jako przykªad rozwa»my poszukiwanie w ªa«cuchu znaków sªowa
l
ropoczynaj¡cego si¦ na zadan¡ liter¦ . W tym celu napiszemy funkcj¦ (zwracaj¡c¡ 0 w
przypadku gdy »aden z wyrazów nie rozpoczyna si¦ od zadanej litery) u»ywaj¡c p¦tli
nie korzystaj¡c z instrukcji
break
function ind = znajdz(v,l)
n = max(size(v))
i = 1
succes = %f
while ~succes & (i <= n)
succes = part(v(i),1) == l
i = i + 1
end
if succes then
ind = i-1
else
ind = 0
end
endfunction
Wykorzystanie instrukcji
break
prowadzi do bardziej naturalnego rozwi¡zania
function ind = znajdz(v,l)
n = max(size(v))
ind = 0
for i=1:n
if part(v(i),1) == l then
ind = i
break
end
end
endfunction
48
while
i
Uwaga: Powy»ej zastosowano funkcj¦ size zamiast odpowiedniejszej dla macierzy zªo»onych
z ªa«cuchów znaków funkcji length6 (przypominamy, »e length zwraca macierz której
warto±ci wspóªczynników okre±laj¡ ilo±¢ znaków w adpowiadaj¡cym ªa«cuchu).
3.4.4 Kilka przydatnych dla funkcji prymitywów
length i size pozwalaj¡cymi otrzyma¢ wymiary przekazanych zmiennych,
pause, resume, disp dzieki którym mo»emy debugowa¢ program dost¦pnych jest jeszcze
kilka u»ytecznych funkcji jak error, warning, arg czy te» type, czy typeof.
Poza funkcjami
Funkcja
Funkcja
error
error
przerywa natychmiast wykonanie funkcji wy±wietlaj¡c przy tym odpowiedni
komunikat. Oto funkcja obliczaj¡ca
n! i sprawdzaj¡ca, czy n 2 N
function [f] = silnia2(n)
// oblicza silnie dla liczby naturalnej
if (n - floor(n) ~=0) | n<0 then
error('Blad w funkcji silnia2 : argument musi byc liczba naturalna')
end
f = prod(1:n)
endfunction
oraz rezultaty jej wykonania
-->silnia2(3)
ans =
6.
-->silnia2(0.56)
!--error 10000 Blad w funkcji silnia2 : argument musi byc liczba naturalna
at line 6 of function silnia2 called by : silnia2(0.56)
Funkcja
Funkcja
warning
warning
pozwala wy±wietli¢ pewien komunikat ostrzegawczy, ale nie przerywa
wykonywanych operacji
function [f] = silnia3(n)
// oblicza silnie dla liczby naturalnej
if (n - floor(n) ~=0) | n<0 then
n = floor(abs(n))
warning('Przekazany argument nie jest liczba naturalna: obliczenia kontynuowa
end
f = prod(1:n)
endfunction
. . . i efekt wykonania
-->fact3(-4.6)
WARNING:Przekazany argument nie jest liczba naturalna: obliczenia kontynuowane dla 4!
ans =
24.
6
Je±li chcemy aby nasza funkcji mogªa poprawnie dziaªa¢ niezale»nie od tego czy
nie nale»y u»ywa¢ konstrukcji
size(v,'r')
lub
size(v,'l')
v
ale zastosowan¡ wªa±nie
49
jest w postaci wiersza czy kolumny
max(size(v)).
v
type(v)
typeof(v)
macierz zmiennych rzeczywistych lub zespolonych
1
constant
macierz boolowska
4
boolean
macierz ªa«cuchów znakowych
10
string
lista
15
list
lista typowana
16
typ listy
funkcja
13
function
typ zmiennej
Tablica 3.1:
Podobnie jak dla funkcji
error
tak i dla funkcji
warning jedynym argumentem jest ªa«cuch
+ do ª¡czenia ªa«cuchów, z których
sprintf pozwalaj¡cej przeksztaªci¢ liczby w
znaków. W powy»szym przykªadzie u»yto operatora
jeden jest otrzymany w wyniku dziaªania funkcji
odpowiadaj¡cy im ªa«cuch znaków zale»ny od wyspecykowanego formatu.
Funkcja
type
Funkcje te pozwalaj¡ pozna¢ typ zmiennej.
danej, natomiast
typeof
et
type
typeof
zwraca warto±¢ liczbow¡ okre±laj¡c¡ typ
ªa«cuch znaków. Tabela 3.1 zawiera odpowiednie warto±ci dla
poznanych rodzajów
zmiennych. Jako przykªad wykorzystania tych funkcji podamy funkcj¦ licz¡c¡ silnie, która
posiada pewne zabezpieczenia na wypadek podania zmiennej nieodpowiedniego typu
function [f] = silnia4(n)
// funkcja silnia bardziej ,,opancerzona''
if type(n) ~= 1 then
error("Blad w funkcji silnia4: podano argument nieodpowiedniego typu...")
end
[nl,nc]=size(n)
if (nl ~= 1) | (nc ~= 1) then
error("Blad w funkcji silnia4: argument nie moze byc macierza...")
end
if (n - floor(n) ~=0) | n<0 then
n = floor(abs(n))
warning('Przekazany argument nie jest liczba naturalna: obliczenia kontynuowane dla
end
f = prod(1:n)
endfunction
Funkcja
Funkcja
arg
argn
i opcjonalne argumety
zwraca dwie liczby okre±laj¡ce ilo±¢ argumentów z jak¡ funkcj¦ wywoªano oraz
ilo±¢ argumentów jakie zwraca. Wywoªanie przyjmuje posta¢
[lhs,rhs] = argn()
gdzie
lhs (ang. left hend side)
okre±la ilo±¢ zwracanych argumentów,
rhs (ang. right hend
side) okre±la ilo±¢ przyj¦tych efektywnie argumentów.
Poni»ej prezentujemy przykªad funkcji z jednym argumentem klasycznym oraz dowoma
opcjonalnymi
function [y] = argopt(x, coefMult, coefAdd)
[lhs, rhs] = argn()
if rhs < 1 | rhs > 3 then
error("Nieprawidlowa ilosc argumentow")
end
50
if ~exists("coef_mult","local") then
coef_mult = 1
end
if ~exists("coef_add","local") then
coef_add = 0
end
y = coef_mult*x + coef_add
endfunction
Funkcja
exists
coefm ultoraz coefa ddzostayokrelone
7
pozwala okre±li¢ czy argumenty
przyjejwywoaniuczynaleyprzypisaimpewnwartodomyln:Uzy
-->y1 = argopt(5)
y1 =
5.
-->y2 = argopt(5, coef_add=10)
y2 =
15.
-->y3 = argopt(5, coef_mult=2, coef_add=6)
y3 =
16.
-->y4 = argopt(5, coef_add=6, coef_mult=2) // y4 powinno byc równe y3
y4 =
16.
3.5
Ró»ne ró»no±ci
3.5.1 Dªugo±¢ identykatorów
Identykatory w Scilabie rozró»niane s¡ na podstawie pierwszych 24 liter
-->a234567890123456789012345 = 1
a23456789012345678901234 =
1.
-->a234567890123456789012345
a23456789012345678901234 =
1.
Oczywi±cie mo»na u»ywa¢ nazw dªu»szych, ale i tak pod uwag¦ branych jest pierwszych 24
liter.
3.5.2 Priorytety operatorów
W Scilabie operatory zwi¡zane z dziaªaniami arytmetycznymi maj¡ wy»szy priorytet ni» operatory sªu»¡ce do porówna«. W tabeli 3.2 przedstawiono operatory arytmetyczne w kolejno±ci
od najwy»szego do najni»szego priorytetu. Dla operatorów logicznych negacja (not) (
7
Dodatkowy argument
local
zaw¦»a zakres poszukiw« zmiennej do bie»¡cej funkcji.
51
'
^ .^
* .* / ./ \
+ Tablica 3.2:
) ma wy»szy priorytet ni» i (and) (&), który z kolei ma wy»szy priorytet ni» lub (or) (|). W
czytaniu/zapisie bardziej zªo»onych wyra»e« mo»na pomóc sobie u»ywaj¡c dodatkowo naw-
8
iasów i robi¡c spacje wokóª wyra»e« .
Tricks.
Wi¦cej szczegóªów mo»na znale¹¢ w
Scilab Bags of
Kilka uwag
1. Jak w wi¦kszo±ci j¦zyków, stosowanie unarnego operatora minus wymaga ostro»no±ci.
Bª¦dny jest zapis
operand1 op - operand2
gdzie
op
jest pewnym operatorem. W takiej sytucji nale»y zastosowac nawiasy
operand1 operator (- operand2)
2. W wyra»eniach typu
operand1 op1 operand2 op2 operand3 op3 operand4
gdzie wszystkie operatory maj¡ ten sam priorytet obliczanie warto±ci wyra»enia odbywa
si¦ na ogóª od lewej do prawej strony
{((operand1 op1 operand2) op2 operand3) op3 operand4}
Dla operatora pot¦gowania kolejno±¢ ta jest odwrotna; zapis
a^(b^c).
a^b^c
Jest to zgodne z matematycznym zapisem takiego dziaªania
traktowany jest jak
ab c
które wªa±nie w
takiej kolejno±ci si¦ wykonuje.
a | b czy a & b
a jak i b a dopiero potem wyko-
3. Inaczej ni» w j¦zyku C obliczanie warto±ci wyra»e« boolowskich postaci
poprzedzone jest obliczeniem zarówno warto±ci wyra»enia
nana zostanie na nich operacja sum czy iloczynu logicznego. St¡d te» poni»sze rozwi¡zanie
wygeneruje bª¡d
while i>0 & temp < v(i)
v(i+1) = v(i)
i = i-1
end
przy próbie obliczenia drugiego wyra»enia (temp
< v(i)) gdy» indeks wektora jest zawsze
liczb¡ wi¦ksz¡ lub równ¡ 1.
3.5.3 Rekursja
O rekursji powiemy gdy funkcja b¦dzie wywoªywa¢ sam¡ siebie.
Prosz¦ spojrze¢ na dwa
poni»sze przykªady (s¡ to standardowe przykªady ilustruj¡ce rekursj¦; drugi z nich, skªadniowo poprawny i dziaªaj¡cy, pokazuje wad¦ rozwi¡za« rekursywnych dªugi czas oblicze« a
tak»e mo»liwo±¢ przepeªnienia stosu)
function f=silnia(n)
// silnia
if n <= 1 then
8
Oczywi±cie nawiasy s¡ niezb¦dne je±li chcemy zmieni¢ priorytet wyra»enia.
52
f = 1
else
f = n*silnia(n-1)
end
endfunction
function f=fib(n)
// oblicza n-ty wyraz ciagu Fibonnaciego:
// fib(0) = 1, fib(1) = 1, fib(n+2) = fib(n+1) + fib(n)
if n <= 1 then
f = 1
else
f = fib(n-1) + fib(n-2)
end
endfunction
3.5.4 Funkcja jest te» zmienn¡
Funkcja w Scilabie mo»e by¢ traktowana jak dowolna inna zmienna, w szczególno±ci mo»e sta¢
si¦ ona argumentem innej funkcji. Przyjrzyjmy si¦ poni»szemu przykªadowi dwóch funkcji
function [y] = f(x)
y = sin(x).*exp(-abs(x))
endfunction
function dessine_fonction(a, b, fonction, n)
// n jest argumentem opcjonalnym o wartosci domyslnej 61
[lhs, rhs] = argn(0)
if rhs == 3 then
n = 61
end
x = linspace(a,b,n)
y = fonction(x)
plot(x,y)
endfunction
Po ich wczytaniu mo»emy wykona¢ nast¦puj¡ce polecenia
-->dessine_fonction(-2*%pi,2*%pi,f)
-->dessine_fonction(-2*%pi,2*%pi,f,21)
Scilab, za pomoc¡ funkcji
deff,
oferuje mo»liwo±¢ bezpo±redniego deniowania funkcji w
±rodowisku (bez potrzeby zapisywania jej w pliku a nast¦pnie wczytywania przez funkcj¦
getf)
deff('[y1,y2,...]=nazwa_funkcji(x1,x2,....)',text)
gdzie
text jest wektorem kolumnowym zªo»onym z ªa«cuchów znaków reprezentujacych kolejne
instrukcje
deff('[y]=f(x)','y = sin(x).*exp(-abs(x))')
Taka mo»liwo±¢ jest interesuj¡ca w wielu przypadkach.
1. W skrypcie wyko»ystujacym prost¡ funkcj¦ która musi by¢ do±¢ cz¦sto modykowana; w
tym przypadku mo»na zdeniowa¢ funkcj¦ za pomoc¡ instrukcji
deff w skrypcie, który nie
przeplata si¦ z innym plikiem, w którym funkcja jest zwycajnie zdeniowana;
pocz¡wszy
od wersji 2.6 mo»na deniowa¢ funkcje w skrypcie wedlug zwycajnej skªadni,
co jest praktyczniejsze ni»
deff;
w naszym skrypcie mo»na wiec napisa¢ funkcje
na pocz¡tku tekstu:
53
// definicja funkcji wykorzystywanych w skrypcie
function
....
endfunction
function
....
endfunction
// poczatek skryptu wlasciwego
....
2. Pozwala ona na dynamczne deniowanie pewnych partii kodu w oparciu o
ju» przeprowadzone dziaªania i/lub dodane nowe czy to z pliku, czy przez
interakcj¦ z u»ytkownikiem na przykªad przez okna dialogowe (patrz tak»e
funkcje
evstr
oraz
execstr).
3.5.5 Okna dialogowe
W przykªadzie z rodziaªu 2 widzieli±my wykorzystanie funkcji
teraktywne pobranie pewnych danych od u»ytkownika.
Funkcja
input pozwalaj¡cej na indisp pozwalaªa natomiast
wyprowadzi¢ pewne informacje na ekran. W Scilabie dost¦pna jest grupa funkcji zwi¡zanych
z oknami dialogowymi, menu, wyborem pliku:
x_mdialog, x_message, xgetfile
x_choices, x_choose, x_dialog, x_matrix,
. Po szczegóªowe informacje z nimi zwi¡zane odsyªamy do
pomocy (zawarte s¡ tam równie» odpowiednie przykªady).
3.5.6 Konwersja ªa«cucha znakowego do wyra»enia
Cz¦sto u»ytecznym okazuje si¦ mo»liwo±¢ ewaluacji wyra»enia podanego w postaci ªa«cucha
znaków (czyli napisu). Konwersji takiej dokona¢ mo»emy za pomoca funkcji
evstr
-->c = "sqrt(3)/2"
c =
sqrt(3)/2
-->d = evstr(c)
d =
0.8660254
W takim ªa«cuchu znaków mo»na u»ywa¢ zdeniowanych uprzenio zmiennych
-->a = 1;
-->b=evstr("2 + a")
b =
3.
Funkcja ta oczywi±cie mo»liwa jest tak»e do zastosowania w stosunku do macierzy zªo»onych
z ªa«cuchów znaków
9
-->evstr(["a" "2" ])
ans =
! 1.
2. !
-->evstr([" a + [1 2]" "[4 , 5]"])
ans =
! 2.
3.
4.
5. !
9
A tak»e list, patrz help.
54
-->evstr(["""a""" """b"""])
ans =
!a b !
Istnieje tak»e funkcja,
// zamiana lancucha na lancuch
execstr,
pozwalaj¡ca wykona¢ instrukc¦ Scilaba podan¡ w formie
ªa«cucha znaków
-->execstr("A=rand(2,2)")
-->A
A =
! 0.2113249
0.0002211 !
! 0.7560439
0.3303271 !
3.6
Czytanie i pisanie . . .
. . . z/do pliku lub okna Scilaba. Scilab posiada dwie rodziny wej±¢/wyj±¢. Powinno si¦ unika¢
mieszania ze sob¡ obsªuguj¡cych je funkcji zwªaszcza gdy operacje te zwi¡zane s¡ z plikiem.
3.6.1 Wej±cie i wyj±cie w stylu Fortranu
W rozdziale drugim widzieli±my jak zapisywa¢ i odczytywa¢ macierz liczb rzeczywistych za
pomoc¡ funkcji
read oraz write.
To samo mo»emy zrobi¢ w stosunku do wektora kolumnowego
zªo»onego z ªa«cuchów znaków
-->v = ["Scilab is free";"Octave is free";"Matlab is ?"];
-->write("toto.dat",v,"(A)")
// zobacz jak wyglada plik toto.dat
-->w = read("toto.dat",-1,1,"(A)")
w =
!Scilab is free
!
!Octave is free
!
!Matlab is ?
!
!
!
!
!
Podczas zapisu dodajemy trzeci argument okre±laj¡cy format zapisu w stylu Fortaranu. Jest
nim ªa«cuch znaków, zawarty pomi¦dzy nawiasami okr¡gªymi, zawieraj¡cy jed¡ lub wi¦cej
specykacji zapisu (rozdzielonych przecinkiem); w przykªadzie powy»ej
A
oznacza, »e chcemy
zapisa¢ ªa«cuch znaków. Przy odczycie drugi i trzeci argument oznaczaj¡ odpowiednio ilo±c
linii (-1 oznacza czytanie do ko«ca pliku) i kolumn. W przypadku macierzy liczbowych nale»y
ponadto poda¢ format okre±laj¡cy precyzj¦ z jak¡ nale»y wynik zapisa¢.
Generalnie mo»liwo±ci Scilaba dotycz¡ce obsªugi plików s¡ identyczne jak dla Fortrana 77,
dlatego te» mo»na szuka¢ informacji na ten temat w ksi¡»kach jemu po±wi¦conych. Poni»ej
podane zostan¡ przykªady zwi¡zane z dost¦pem sekwencyjnym do plików tekstowych.
Otwieranie pliku
Plik otwieramy za pomoc¡ funkcji
file
55
[unit, [err]]=file('open', file-name ,[status])
gdzie
file-name
jest ªa«cuchem znaków okre±laj¡cym plik (ewentualnie poprzedzonym ±cie»k¡
dost¦pu, je±li nie znajduje si¦ on w »adnym z katalogów b¦d¡cych w ±cie»ce przeszukiwania
Scilaba; ±cie»k¦ t¡ mo»na zmieni¢ za pomoc¡ funkcji
status
chdir).
przyjmuje jedn¡ z nast¦puj¡cych warto±ci
new
w celu otworzenia nowego pliku; je±li plik o podanej nazwie istnieje, generowany
jest bª¡d;
old
w celu otworzenia ju» istniej¡cego pliku; je±li plik o podanej nazwie nie istnieje,
generowany jest bª¡d;
unknow
je±li plik o podanej nazwie nie istnieje, to zostanie utowrzony, w przeciwnym
razie zostanie otwarty plik ju» istniej¡cy;
W przypadku braku argumentu
status przyjmowana jest dla niego domy±lna warto±¢ new.
unit jest zmienn¡ za pomoc¡ której b¦dziemy odwoªywa¢ si¦ do otwieranego pliku podczas
operacji plikowych;
Je±li obecny b¦dzie argument
err
mo»liwe b¦dzie stwierdzenie czy operacja otwierania
pliku si¦ powiodªa; w przeciwnym razie Scilab generuje bª¡d. Warto±¢ równa
brak b¦dów zwi¡zanych z otwieraniem pliku.
W innym przypadku pisz¡c
0
oznacza
error(err)
mo»na zobaczy¢ troch¦ wi¦cej szczegóªów na temat napotkanego bª¦du
-->error(240) // zakladamy, ze err=240
!--error 240
File error(240) already exists or directory write access denied
U»ycie funkcji
xgetfile pozwala na interaktywny wybór pliku przez przegl¡danie drzewa
hierarchi plików i katalogów.
Pisanie i czytanie
Zaªó»my, »e mamy otwarty plik.
Je±li plik ju» istniaª, czytanie/pisanie rozpocznie si¦ od
pocz¡tku (b¦dziemy mówi¢, »e wska¹nik pliku zostaª ustawiony na pocz¡tek pliku).
chcemy pisa¢ na koniec pliku nale»y wcze±niej, za pomoc¡ funkcji
Je±li
file("last", unit),
ustawi¢ wska¹nik pliku na jego koniec. Powrót na pocz¡tek mo»liwy jest po wykonaniu instrukcji
file("rewind", unit).
n punktów Pi = (xi ; yi ) oraz m odcinków; ka»dy opisany jako jeden segment Pi P!j
przez podanie numeru (w tablicy punktów) punktu pocz¡tkowego (tutaj i) i ko«cowego (tutaj
j ). Poni»ej przedstawiamy format pliku
Oto pierwszy przykªad. Chcemy zapisa¢ do pliku list¦ odcinków na pªaszczy¹nie. W tym celu
rozwa»amy
linia z tekstem
n
x_1 y_1
...
x_n y_n
m
i1 j1
...
im jm
56
W linii z tekstem mo»emy zawrze¢ pewne dodatkowe informacje zwi¡zane z plikiem. Nast¦pnie
podajemy ilo±¢ punktów oraz ich wspóªrz¦dne. Dalej za± ilo±¢ odcinków i numery wierzchoªków
text, punkty
P wymiaru (n; 2), odcinki za± przez macierz connect wymiaru (m; 2). Wszystkie
je tworz¡cych. Zaªó»my, »e linia z tekstem reprezentowana jest przez zmienn¡
przez macierz
te informacje zostan¡ zapisane po wprowadzeniu nast¦puj¡cego ci¡gu instrukcji
write(unit,texte)
write(unit,size(P,1))
write(unit,P)
write(unit,size(connect,1))
write(unit,connect)
file("close",unit)
//
//
//
//
//
//
zapisanie linii z tekstem
zapisanie ilosci punktow
zapisanie wspolrzednych punktow
zapisanie ilosci odcinkow
zapisanie punktów definiujacych odcinki
zamkniecie pliku
Efekt mo»e wygl¡da¢ jak poni»ej
przypadkowy wielokat
5.0000000000000
0.28553641680628
0.86075146449730
0.84941016510129
0.52570608118549
0.99312098976225
5.0000000000000
1.0000000000000
2.0000000000000
3.0000000000000
4.0000000000000
5.0000000000000
0.64885628735647
0.99231909401715
5.0041977781802D-02
0.74855065811425
0.41040589986369
2.0000000000000
3.0000000000000
4.0000000000000
5.0000000000000
1.0000000000000
co nie prezentuje si¦ elegancko, gdy» nie podali±my formatu w jakim nale»y dane zapisa¢. Jak
10 . Ponadto tekst zostaª
wida¢ liczby caªkowite traktowane s¡ przez Scilaba jak rzeczywiste
poprzedzony spacj¡ (której nie byªo w
text).
W celu poprawienia tych niedogodno±ci, nale»y
doda¢ specykacj¦ okre±laj¡c¡ sposób traktowania danych
Dla liczb caªkowitych nale»y u»y¢
Ix,
gdzie
x
jest dodatni¡ liczb¡ okre±laj¡c¡ szeroko±¢
pola.
y za±
szeroko±¢ mantysy; wyj±cie przyjmuje wówczas posta¢ [znak]0.mantysaE[znak]wykladnik.
Dla liczb rzeczywistych nale»y u»y¢
Ex.y,
gdzie
x
okre±la caªkowit¡ szeroko±¢ pola,
Dla liczb zmiennopozycyjnych podwójnej prezycji otrzymamy w ten sposób zapis z 16
cyframi znacz¡cymi i wykªadnikiem o warto±ciach pomi¦dzy -330 i +300 co ª¡cznie daje
szeroko±¢ okoªo 24 znaków. Tak wi¦c mo»na u»y¢ formatu
E24.16 (w zale»nie od wielko±ci
liczb oraz oczekiwanej formy ich prezentacji inne formaty mog¡ okaza¢ si¦ bardziej odpowied-
nie).
Dla unikni¦cia spacji na pocz¡tku tekstu nale»y u»y¢
A.
Rozwa»aj¡¢ poprzedni przykªad mo»emy uzyska¢ bardziej elegancki format zapisu (zakªadamy,
»e ilo±¢ punktów jest nie wi¦ksza jak 999)
write(unit,texte,"(A)")
write(unit,size(P,1),"(I3)")
10
// zapisanie linii z tekstem
// zapisanie ilosci punktow
Od wersji 2.5 mamy do dyspozycji typy int8, int16 et int32; patrze
57
Help.
mopen
mclose
mprintf, mscanf
mfprintf, mfscanf
msprintf, msscanf
otwieranie pliku
zamykanie pliku
pisanie i czytanie z okna Scilaba
pisanie i czytanie z pliku
pisanie i czytanie z ªa«cucha znaków
Tablica 3.3:
write(unit,P,"(2(X,E24.16))")
write(unit,size(connect,1),"(I3)")
write(unit,connect,"(2(X,I3))")
file("close",unit)
(format
//
//
//
//
zapisanie wspolrzednych punktow
zapisanie ilosci odcinkow
zapisanie punktow definiujacych odcinki
zamkniecie pliku
X odpowiada za wypisanie jednego biaªego znaku, natomiast powtórzenie 2(X,E24.16)
oznacza »e w tej samej lini chcemy wypisa¢ dwa pola zawieraj¡ce biªy znak, po nim za± liczb¦
zmiennoprzecinkow¡ zapisan¡ na 24 znakach)
przypadkowy wielokat
5
0.2855364168062806E+00
0.8607514644972980E+00
0.8494101651012897E+00
0.5257060811854899E+00
0.9931209897622466E+00
5
1 2
2 3
3 4
4 5
5 1
0.6488562873564661E+00
0.9923190940171480E+00
0.5004197778180242E-01
0.7485506581142545E+00
0.4104058998636901E+00
Aby odczyta¢ utworzony w ten sposób plik mo»na u»y¢ nast¦puj¡cej sekwencji instrukcji
texte=read(unit,1,1,"(A)")
n = read(unit,1,1)
P = read(unit,n,2)
m = read(unit,1,1)
connect = read(unit,m,2)
file("close",unit)
//
//
//
//
//
//
odczytanie
odczytanie
odczytanie
odczytanie
odczytanie
zamkniecie
linii z tekstem
ilosci punktow
wspolrzednych punktow
ilosci odcinkow
punktow definiujacych odcinki
pliku
Przygl¡daj¡c si¦ podanym przykªadom, wida¢, »e zamykanie pliku odbywa si¦ za pomoc¡
insrukcji
file(close,unit).
Czytanie b¡d¹ pisanie do okna Scilaba odbywa si¦ przy pomocy, odpowiednio, funkcji
= %io(1)
et
unit = %io(2).
stosuj¡c standardow¡ funkcj¦
unit
Przy wypisywaniu mo»na ró»nie» osi¡gn¡¢ lepsze efekty ni»
disp
(patrz przykªad w rozdziale Ciekawostki w sekcji Proste
instrukcje i funkcje Scilaba, funkcja MonteCarlo).
3.7
Wej±cie i wyj±cie w stylu C
Podstawowe funkcje zwi¡zane z obsªuga plików przedstawiono w tabeli 3.3.
teraz wyja±ni¢ kwestie zwi¡zane z u»yciem funkcji pisz¡cych na przykªadzie
58
Postaramy si¦
mprintf.
n = 17;
m = -23;
a = 0.2;
b = 1.23e-02;
c = a + %i*b;
s = "kukulka";
mprintf("\n\r
mprintf("\n\r
mprintf("\n\r
mprintf("\n\r
mprintf("\n\r
mprintf("\n\r
n
a
a
a
c
s
=
=
=
=
=
=
%d, m = %d", n, m); // %d dla calkowitych
%g", a);
// %g dla rzeczywistych
%e", a);
// %e dla rzeczywistych (notacja z wykladnikiem)
%24.16e", a);
// okreslenie ilosci wyswietlanych cyfr
%g + i %g", real(c), imag(c)); // liczba zespolona
%s", s);
// %s dla lancucha znakow
Zapisuj¡c powy»sze instrukcje w pliku i wywoªuj¡c je poleceniem
exec("demo_mprintf.sce");
jako wyj±cie powinni±my zobaczy¢
n
a
a
a
c
s
=
=
=
=
=
=
17, m = -23
0.2
2.000000e-01
2.0000000000000001e-01
0.2 + i 0.0123
kukulka
Do peªnego zrozumienia brakuje jeszcze kilka wyja±nie«
Konstrukcja
%x
\n\r powoduje przej±cie do nowej linii (w systemie Unix wystarczy samo \n).
jest dyrektyw¡ formatuj¡c¡ wyj±cie, to znaczy okre±laj¡c¡ w jaki sposób nale»y trak-
towa¢ (i w konsekwencji wy±wietli¢) zmienn¡. I tak
1.
%d
2.
%e dla liczb rzeczywistych przedstawianych w notacji naukowej (z wykªadnikiem).
dla liczb caªkowitych
cie powinno przyjmowa¢ posta¢
[ ]c0 :c1 :::c6 ed1 d2 [d3 ].
rozdzielone przecinkiem (pomi¦dzy znakiem
Wyj±-
Dodaj¡c dwie liczby caªkowie
% oraz e) pkre±lamy caªkowit¡ ilo±¢ znaków
na jakich liczba zostanie zapisana oraz ilo±¢ cufr po przecinku.
3.
%g
powoduje wy±wietlenie liczby bez wykªadnika (je±li mie±ci si¦ ona w odpowiednim
przedziale) lub z wykªadnikiem.
4.
%.3f
powoduje wy±wietlenie liczby rzeczywistej bez wykªadnika zapisanej na 5 znakach
i 3 cyframi po przecinku.
5.
%s
dla ªa«cucha znaków.
Ka»dej dyrektywie musi odpowiada¢ jedna warto±¢, która ma zosta¢ wy±wietlona (pochodz¡ca
od zmiennej, wyra»enia czy te» staªej). Je±li chcemy wy±wietli¢ 4 liczby caªkowite musimy
poda¢ 4 dyrektywy
mprintf("%d %d %d %d", expr1, expr2, expr3, expr4);
Ciekawostka
Dlaczego wy±wietlenie liczby
0:2 w formacie 24.16e wygl¡da dziwnie? Wynika to z niemo»no±ci
0:2 w systemie dwójkowym.
reprezentacji z odpowiedni¡ precyzj¡ liczby
59
3.8
Uwagi zwi¡zane z szybko±ci¡
Zobaczmy dwa przykªady przedstawiaj¡ce kilka znanych sposobów tutu. Zaªó»my, »e chcemy
znale¹¢ (obliczy¢ tutu) macierz Vandermondea
2
1 t1 t21 : : :
66 1 t2 t22 : : :
A = 6 .. .. .. ..
4. . . .
3
tn1
tn2 7
7
.
.
.
1 tm t2m : : : tnm
75
Oto narzucaj¡cy si¦ w pierwszej chwili kod
function A=vandm1(t,n)
// obliczenie macierzy Vandermonde A=[a(i,j)] 1<= i <= m
//
1<= j <= n+1
// gdzie a(i,j) = ti^(j-1)
// t musi byc wektorem kolumnowym o m skladowych
m=size(t,'r')
for i = 1:m
for j = 1:n+1
A(i,j) = t(i)^(j-1)
end
end
endfunction
Poniewa» w Scilabie a priori nie deklaruje si¦ rozmiaru macierzy ani innych obiektów dlatego
nie ma potrzeby informowania funkcji, »e nasza macierz
A
jest wymiaru
(m; n + 1).
jak post¦puj¡ obliczenia Scilab musi upora¢ si¦ ze zmianami w macierzy
A
W miar¦
wynikaj¡cymi ze
i = 1 A jest wektorem liniowym o j skªadowych, dla i > 1 A jest
(i; n + 1), mamy wi¦c n + m 1 zmian wymiaru macierzy A co oczywi±cie
zwi¦kszania jej wymiaru (dla
macierz¡ wymiaru
zwi¡zane jest z potrzeb¡ po±wi¦cenia na to pewnej ilo±ci czasu, tym wi¦kszej im wi¦ksza jest
macierz). Problem ten mo»na obej±¢ wykorzystuj¡c pseudo-deklaracj¦
zeros(m,n+1)
function A=vandm2(t,n)
// identycznie jak w vandm2 oprocz pseudo-deklaracji dla A
m=size(t,'r')
A = zeros(m,n+1)
// pseudo-deklaracja
for i = 1:m
for j = 1:n+1
A(i,j) = t(i)^(j-1)
end
end
endfunction
Tym oto sposobem pozbywamy si¦ tego problemu i zyskujemy cenny czas, który mo»na
spo»ytkowa¢ efektywniej. :
-->t = linspace(0,1,1000)';
-->timer(); A = vandm1(t,200); timer()
ans =
6.04
-->timer(); A = vandm2(t,200); timer()
ans =
1.26
A instrukcj¦
ones(m,n+1) (unikamy wtedy obliczania pierwszej kolumny ), wykonuj¡c jedynie mno»enie
aij = aij 1 ti (to natomiast pozwala unikn¡¢ oblicze« zwi¡zanych z pot¦gowaniem) widzimy
Mo»na próbowa¢ zoptymalizowa¢ ten kod stosuj¡c przy inicjalizacji macierzy
odwracaj¡c dwie p¦tle, ale co± zyskujemy. Lepsze rezultaty mo»na osi¡gn¡¢ zauwa»aj¡c, »e
konstrukcja macierzy
A
umo»liwia wykorzystanie instrukcji wektorowych
60
function A=vandm5(t,n)
// dobra metoda: uzycie zapisu macierzowego
m=size(t,'r')
A=ones(m,n+1)
for i=1:n
A(:,i+1)=t.^i
end
endfunction
function A=vandm6(t,n)
// wskaznik na vandm5 z malym ulepszeniem
m=size(t,'r')
A=ones(m,n+1)
for i=1:n
A(:,i+1)=A(:,i).*t
end
endfunction
Prowadzi to do znacznego poprawienia szybko±ci oblicze«
-->timer(); A = vandm5(t,200); timer()
ans =
0.05
-->timer(); A = vandm6(t,200); timer()
ans =
0.02
Oto drugi przykªad: zadanie polega na rozwini¦ciu funkcji kapelusz (patrz rysunek 3.2) w
wielu punktach (liczby rzeczywiste ustawione w wektor lub macierz):
8
0
>
>
< t
(t) = bc
>
>
:c
ta
si a t b
si b t c
0 si t c
si
a
a
t
b
Chc¡c zdeniowa¢ t¡ funkcj¦ w kawaªkach rozwijanie w punkcie wymaga¢ bedzie dodatkowych
Rysunek 3.2: Funkcja kapelusz
testów. Gdy obliczenia b¦d¡ dotyczy¢ wielu punktów dobrze by byªo zastanowi¢ si¦ nad mo»liwo±i¡ wektoryzacji oblicze«. Pierwszy kod realizuj¡cy postawione zadanie mógªby wygl¡da¢
nast¦puj¡co
function [y]=phi1(t,a,b,c)
// rozwija funkcje ,,kapelusz'' (z parametrami a, b oraz c) na wektorze
// (czytaj macierzy) t w sensie ,,element po elemencie''
// a,b oraz c musza spelniac zaleznosc a < b < c
[n,m] = size(t)
y = zeros(t)
for j=1:m, for i=1:n
if t(i,j) > a then
if t(i,j) < b then
y(i,j) = (t(i,j) - a)/(b - a)
elseif t(i,j) < c then
y(i,j) = (c - t(i,j))/(c - b)
61
end
end
end, end
endfunction
daj¡c w efekcie
-->a = -0.2 ; b=0 ; c=0.15;
-->t = rand(200000,1)-0.5;
-->timer(); y1 = phi1(t,a,b,c); timer()
ans =
2.46
Kolejna próba, w której wykorzystujemy funkcj¦
macierzy liczb rzeczywistych wedªug schematu:
bool2s
konwertuj¡c¡ macierz boolowsk¡ do
prawda przechodzi w 1, faªsz przechodzi w 0
function [y]=phi2(t,a,b,c)
// rozwija funkcje ,,kapelusz'' (z parametrami a, b oraz c) na wektorze
// (czytaj macierzy) t w sensie ,,element po elemencie''
// a,b oraz c musza spelniac zaleznosc a < b < c
Indicatrice_a_b = bool2s( (a < t) & (t <= b) )
Indicatrice_b_c = bool2s( (b < t) & (t < c ) )
y = Indicatrice_a_b .* (t - a)/(b - a) + Indicatrice_b_c .* (c - t)/(c - b)
endfunction
function [y]=phi3(t,a,b,c)
// jak phi2 z niewielka optymalizacja
t_le_b = ( t <= b )
Indicatrice_a_b = bool2s( (a < t) & t_le_b )
Indicatrice_b_c = bool2s( ~t_le_b & (t < c) )
y = Indicatrice_a_b .* (t - a)/(b - a) + Indicatrice_b_c .* (c - t)/(c - b)
endfunction
okazuje si¦ lepszym rozwi¡zaniem
-->timer(); y2 = phi2(t,a,b,c); timer()
ans =
0.12
-->timer(); y3 = phi3(t,a,b,c); timer()
ans =
0.12
-->timer(); y4 = phi4(t,a,b,c); timer() // patrz dalej na definicje phi4
ans =
0.1
Uwagi
Niewielka optymalizacja w
phi2
nie przyniosªa »adnych zysków (jak miaªo to natomiast
miejsce dla poprzedniej wersji Scilaba uruchomionej na innej maszynie);
Kod
phi4
korzysta z funkcji
find,
która jest bez w¡tpienia bardziej naturalna i prostsza
w u»yciu: dla wektora boolowskiego
b(i)=%t
b
zwraca ona wektor
i
zªo»ony z indeksów takich, »e
(pusty gdy wszystkie warto±ci s¡ faªszem). Przykªad
-->x = rand(1,6)
x =
! 0.8497452
0.6857310
0.8782165
62
0.0683740
0.5608486
0.6623569 !
-->ind = find( 0.3<x & x<0.7 )
ind =
! 2.
5.
6. !
Dla macierzy boolowskiej
A
otrzymujemy tak¡ sam¡ list¦ je±li przyjmiemy, »e macierz jest
du»ym wektorem gdzie elementy uªo»one s¡ kolumna po kolumnie. St¡d korzystaj¡c z
drugiego argumentu mo»na uzyska¢ list¦ z indeksami kolumn i wierszy w których speªniony
jest warunek
-->A = rand(2,2)
A =
! 0.7263507
0.5442573 !
! 0.1985144
0.2320748 !
-->[il,ic]=find(A<0.5)
ic = ! 1.
2. !
il = ! 2.
2. !
Spójrzmy teraz na kod funkcji
phi4
function [y]=phi4(t,a,b,c)
// uzycie funkcji find jest bardziej naturalne
t_le_b = ( t <= b )
indices_a_b = find( a<t & t_le_b )
indices_b_c = find( ~t_le_b & t<c )
y = zeros(t)
y(indices_a_b) = (t(indices_a_b) - a)/(b - a)
y(indices_b_c) = (c - t(indices_b_c))/(c - b)
endfunction
Wniosek: je±li obliczenia trwaj¡ za dªugo, spróbujmy dokona¢ wektoryzacji. Je±li taka operacja nie jest mo»liwa lub niewystarczaj¡ca, nie pozostaje nic innego jak napisanie istotnych
fragmentów w C lub Fortranie 77.
3.9
‚wiczenia
1. Napisz funkcj¦ rozwi¡zuj¡c¡ ukªad równa« liniowych z górn¡ macierz¡ trójk¡tn¡.
funkcji
size
U»yj
pozwalaj¡cej uzyska¢ wymiary macierzy
[n,m]=size(A)
Za pierwszym razem napisz klasyczny algorytm wykorzystuj¡c dwie p¦tle.
Nast¦pnie
spróbuj zast¡pi¢ p¦tle instrukcj¡ macierzow¡. W celu przetestowania swojej funkcji mo»na
wygenerowa¢ macierz zªo»on¡ z elementów pseudo-losowych i wydoby¢ z niej macierz
trójk¡tn¡ poleceniem
A=triu(rand(4,4))
2. Rozwi¡zanie ukªadu równa« ró»niczkowych pierwszego rz¦du
dx
(t) = Ax(t); x(0) = x0 2 Rn ; x(t) 2 Rn ; A 2 Mnn (R)
dt
uzyska¢ mo»na wykorzystuj¡c eksponent macierzy (patrz kurs analizy, rok pierwszy).
x(t) = eAt x0
Poniewa» Scilab posiada funkcj¦ licz¡c¡ eksponent macierzy (expm) pozostaje jeszcze kilka
rzeczy do zrobienia.
Chcemy otrzyma¢ rozwi¡zanie dla
63
t
2 [0; T ].
W tym celu mo»na
znale¹¢ liczb¦
n wystarczaj¡co du»¡ na tym przedziale tk = kt, t = T=n oraz wykorzysta¢
wªasno±ci exponent w celu uproszczenia oblcze«
x(tk ) = eAkt x0 = ek(At) x0 = (eAt )k x0 = eAt x(tk 1 )
At, nast¦pnie wykona¢ n mno»e« macierzy
x(t1 ); x(t2 ); : : : ; x(tn ). Napisz skrypt rozwi¡zuj¡cy równanie
Zatem wystarczy obliczy¢ exponentel macierzy
wektorowych aby otrzyma¢
ró»niczkowe postaci (oscylacje z amortyzacj¡)
x00 + x0 + kx = 0;
przyjmuj¡c na przykªad
= 0:1; k = 1; x(0) = x0 (0) = 1
które przyjmuje oczywi±cie posta¢ ukªadu dwóch równa« pierwszego rz¦du. Na zako«czenie mo»na zobrazowa¢ zmiany
x jako funkcj¦ czasu a nast¦pnie trajektorj¦ w przestrzeni fa-
zowej. Pomi¦dzy oknami gracznymi mo»na przechodzi¢ za pomoc¡ funkcji
-->
-->
-->
-->
-->
xset("window",window
//koniec obiczen
xset(``window'',0) // wybor okna o numerze 0
instrukcje dla pierwszego rysunku (który pokaze sie w oknie 0)
xset(``window'',1) // wybor okna o numerze 1
instrukcje dla drugiego rysunku (który pokaze sie w oknie 1)
[i,info]=intervalle_de(t,x) dla okre±lenia przedziaªu i takiego, »e xi t xi+1 za pomoc¡ metody dychotomii (skªadowe wektora x s¡ takie »e xi < xi+1 ). Gdy
t 2= [x1 ; xn ] zmienna boolowska info powinna przyjmowa¢ warto±¢ równ¡ %f (oraz %t w
3. Napisz funkcj¦
przeciwnym razie).
myhorner tak aby mogªa dziaªa¢ w przypadku gdy argument t jest macierz¡
p (takiego samego wymiaru jak t) gdzie ka»dy wspóªczynodpowiada rozwini¦ciu wielomianu t(i,j)).
4. Napisz funkcj¦
(funkcja powinna zwraca¢ macierz
nik
(i; j )
5. Napisz funkcj¦
[y] = sygnal_fourier(t,T,cs),
która zwraca szereg Fouriera wykorzys-
tuj¡c funkcje
2t
2t
4t
4t
f1 (t; T ) = 1; f2 (t; T ) = sin( t); f3 (t; T ) = cos( ); f4 (t; T ) = sin( ); f5 (t; T ) = cos( ); T
T
T
T
zamiast funkcji eksponenet. T jest parametrem (okres), sygnaª za± opisywany jest przez
przez wektor cs zªo»ony ze wspóªczynników w bazach f1 ; f2 ; f3 ; Ilo±¢ funkcji uzyska¢
length zastosowanej do cs. Zaleca si¦ wykorzystanie funkcji pomocniczej [y]=f(t,T,k) obliczaj¡cej fk (t; T ). Wszystko to powinno pozwala¢ na stosowanie
dla wektora czy macierzy instants t co pozwoli na ªatwe zobrazowanie sygnaªu
mo»na dzi¦ki instrukcji
-->
-->
-->
-->
-->
-->
T = 1 // okres
t = linspace(0,T,101) // momenty ...
cs = [0.1 1 0.2 0 0 0.1] // sygnal ze skladowa ciagla
// fundamentalna, bez harmonicznej 1 (okres 2T) ale z harmoniczna 2
[y] = sygnal_fourier(t,T,cs); // obliczenie sygnalu
plot(t,y) // wykres
6. Oto funkcja licz¡ca iloczyn wektorowy dwóch wektorów
function [v]=prod_vect(v1,v2)
// iloczyn wektorowy v = v1 /\ v2
v(1) = v1(2)*v2(3) - v1(3)*v2(2)
v(2) = v1(3)*v2(1) - v1(1)*v2(3)
v(3) = v1(1)*v2(2) - v1(2)*v2(1)
endfunction
64
Dokonaj wektoryzacji tego kodu w taki sposób aby obliczac w (tej) jednej funkcji
produkt wektorowy
vi
= 1
zawierajacej te wektory.
7.
Spotkanie :
vi
^ vi
2
gdzie
vi, vi
1
i
vi
2
function [v]=pro
oznaczaj¡ i-t¡ kolumn¦ macierzy (3,n)
Pan A i Pani B zamierzaj¡ spotka¢ si¦ mi¦dzy godzin¡ 17:00 a 18:00. Ka»de z
nich przyb¦dzie niezale»nie od drugiego pomi¦dzy
[17; 18].
Pani B b¦dzie czeka¢ 5 minut
zanim odejdzie, Pan A 10 minut.
(a) Jakie jest prawdopodobie«stwo, »e si¦ spotkaj¡? (odp. 67/288)
(b) Znajd¹ (przybli»one) wyniki przez symulacj¦: napisz funkcj¦
prawdopodobie«stwo empiryczne spotkania przy
m próbach.
[p] = rdv(m)
(c) Przetestuj dziaªanie swojej funkcji dla coraz wi¦kszych warto±ci
65
m.
zwracaj¡c¡
Rozdziaª 4
Graka
W zakresie tworzenia graki Scilab posiada wiele mo»liwo±ci zarówno je±li bra¢ pod uwag¦ operacje niskopoziomowe jak te» bardziej zlo»one funkcje pozwalaj¡ce operowa¢ skomplikowanymi
obiektami. W dalszym ci¡gu zostanie wyja±niona jedynie maªa cz¦±¢ dost¦pnych mo»liwo±ci.
Uwaga:
Dla osób znaj¡cych instrukcje graczne MATLABA Stephane Mottelet napisaªa (tutu
czy napisal) bibliotek¦ funkcji gracznych wywoªywanych w stylu MATLABA; dost¦pna jest
ona pod adresem
http://www.dma.utc.fr/~mottelet/scilab/
4.1
Okna graczne
Wywoªanie instrukcji gracznej takiej jak
plot czy plot3d powoduje umieszczenie rysowanego
obrazu w oknie racznym o numerze 0. Wywoªanie funkcji gracznej powoduje na ogóª powstanie nowego obrazu na ju» istniej¡cym, st¡d potrzeba uprzedniego wymazania zawarto±ci
okna przy pomocy funkcji
aj¡c z menu
File
opcj¦
xbasc(). Wymazania zawarto±ci okna mo»na tak»e dokona¢ wybierclear. Manipulowanie oknami mo»liwe jest dzieki nast¦puj¡cym
funkcjom
xset("window",num)
num
okno o numerze
staje si¦ oknem bie»¡cym;
je±li »adne okno nie istniaªo to zostanie utworzone
xselect()
uaktywnia bie»¡ce okno;
je±li »adne okno nie istniaªo to zostanie utworzone
xbasc([num])
wymazuje zawarto±¢ okna o numerze
num
;
je±li zostanie pomini¦ty numer to wymazana zostanie
zawarto±¢ bie»¡cego okna
xdel([num])
powoduje zamkni¦cie okna o numerze
num
;
je±li zostanie pomini¦ty numer to zamkni¦te zostanie
bie»¡ce okno
Jako generaln¡ zasad¦ mo»na przyj¡¢, »e po wybraniu bie»¡cego okna (przez
xset("window",num))
xset("nom",a1,a2,...) mo»emy dokonywa¢ zmian w parametrach
nom okre±la nazw¦ parametru, który chcemy zmieni¢ jak na przykªad
chcemy dostosowa¢ grybo±¢ strzaªek czy colormap gdy chcemy zmieni¢ u»y-
za pomoca instrukcji
zwi¡zanych z oknem.
thickness
gdy
wan¡ palet¦ kolorów. Za nazw¡ podajemy jeden lub wi¦cej argumentów wmaganych do ustawienia nowej warto±ci parmetru. Zbiór tych parametrów nazywany jest kontekstem gracznym;
ka»de okno posiada swój taki kontekst. W celu zdobycia wi¦kszej ilo±¢ informacji na temat
parametów (których jest caªkiem pokaŸny zbiór) odsyªsamy do
Library.
Help-u
i tematu
Graphic
W wi¦kszo±ci sytuacji mog¡ one by¢ zmieniane interaktywnie przez menu graczne,
ukazuj¡ce si¦ po wydaniu polecenia
xset().
66
Uwaga: W tym menu dost¦pne jest równie»
(
podokno opisuj¡ce kolory; nie jest jenak mo»liwe wprowadzanie zmian do tego» opisu.
ina funkcji
[a1,a2,...]=xget('nazwa')
Rodz-
pozwala otrzyma¢ parametry zwi¡zane z pewnym
kontekstem gracznym.
4.2
Wprowadzenie do
plot2
Wcze±nie mieli±my ju» do czynienia z prosta instrukcj¡
wi¦cej krzywych lepiej stosowa¢ funkcj¦
plot2d.
plot.
Je±li jednak zamierzamy wykre±lic
Najpro±ciej mo»na j¡ u»y¢ jak to pokazano
poni»ej
x=linspace(-1,1,61)'; // odci\k{e}te (wektor kolumnowy)
y = x.^2; // rz\k{e}dne (równie\.z wektor kolumnowy)
plot2d(x,y) // --> il lui faut des vecteurs colonnes ! tutu
Doªó»my teraz inn¡ krzyw¡ . . .
ybis = 1 - x.^2;
plot2d(x,ybis)
xtitle("Krzywe...")
// dodajemy tytu\l{}
1 ni» poprzednie
. . . i jeszcze jedn¡, która tutu jest w innej skali
yter = 2*y;
plot2d(x,yter)
Zauwa»my, »e Scilab przeskalowaª okno tak aby zmie±ciªa si¦ w nim trzecia krzywa, ale tak»e
odrysowaª dwie poprzednie krzywe w nowej skali (wydaje si¦ to naturalne, ale mechanizm ten
nie byª obecny a» do wersji 2.6 wprowadzaj¡c czesto w bªad). Mo»liwe jest wykre±lenie tych
trzech krzywych za jednym razem
xbasc() // aby wyczy\'scic obszar rysowania
plot2d(x,[y ybis yter]) // konkatenacja macierzy
xtitle("Krzywe...","x","y") // tytu\l{} i nazwy dla obu osi
Otrzymujemy w ten sposób wykres podobny do tego przedstawionego na rysunku 4.1.
Rysunek 4.1: Les fonctions
W
x2 , 1 x2 et 2x2
plot2d(Mx,My)
nc jest równa ilo±ci
krzywych a i-ta krzywa jest otrzymywana na podstawie wektorów Mx(:,i) (odci¦te) i My(:,i)
celu jednoczesnego wykre±lenia kilku krzywych, instrukcja przyjmuje posta¢
gdzie
Mx
(rz¦dne).
oraz
My
s¡ macierzami o identycznym wymiarze, ilo±¢ kolumn
W sytuacji gdy wektor odci¦tych jest taki sam dla wszystkich krzywych (jak w
naszym przypadku), mo»na poda¢ go jeden raz zamiast powtarza¢
zamiast
4.3
plot2d([x x ..
plot2d
x],My)).
nc
razy (plot2d(x,My)
z argumentami opcjonalnymi
Ogólna skªadnia przedstawia si¦ nast¦puj¡co
plot2d(Mx,My <,opt_arg>*)
gdzie
1
2
<,opt_arg>*
oznacza opcjonalny ci¡g dodatkowych argumentów postaci
2
Pod poj¦ciem skali rozumiemy tutaj obszar w jakim zostanie wykre±lona krzywa oraz ewentualne dodatkowe cechy.
argumentFormalny = argumentEfektywny
67
sªowoKluczowe=warto±¢
podanych w dowolnej kolejno±ci. Poka»emy podstawowe epcje przy pomocy kilku przykªadów
1.
Wybór koloru i deniowanie legendy W poprzednim przykªadzie mo»na byªo zaobserwowa¢, »e Scilab wykre±liª 3 krzywe przy u»yciu 3 ró»nych (pierwszych) kolorów okre±lonch
w domy±lnej palecie kolorów
1
czarny
5
czerwony
23
oletowy
2
niebieski
6
oªkowo-ró»owy
26
br¡zowy
3
jasno-zielony
13
ciemno-zielony
29
ró»owy
4
cyan
16
jasno-niebieski tutu
32
jaune orangé
xset() pozwala na ich zmian¦ 3 . Celem wybrania koloru u»ywamy zapisu
styl=vect, gdzie vect jest wektorem liniowym zawieraj¡cym numery kolorów dla ka»dej
krzywej. Legend¦ otrzymujemy pisz¡c leg=str, gdzie str jest ªañcuchem znaków postaci
leg1@leg2@... w którym legi jest podpisem dla i-tej krzywej. Oto przykªad (porówaj
Instrukcja
rysunek (4.2)) :
x = linspace(0,15,200)';
y = besselj(1:5,x);
xbasc()
plot2d(x, y, style=[2 3 4 5 6], leg="J1@J2@J3@J4@J5")
xtitle("Funkcje Bessela J1, J2,...","x","y")
Poniewa» kolejno±¢ argumentów opcjonalnych nie jest istotna równie dobrze mo»na napisa¢
plot2d(x, y, leg="J1@J2@J3@J4@J5", style=[2 3 4 5 6])
Rysunek 4.2: Wybrany styl i legenda
2.
Wkresy zawieraj¡ce symbole Czasami, gdy wa»ne jest wyraŸne wskazanie punktów
przez które wykres przechodzi, przydatne mog¡ okaza¢ si¦ znaczniki tutu. Mo»emy wybra¢
jeden z kilku rodzajów zancznika przedstawionych poni»ej
styl
0
symbol
-1
-2
-3
-4
-5
-6
-7
-8
+ } 4 5 |
-9
Dla przykªadu spróbujmy (porównaj rysunek (4.3)) :
x = linspace(0,2*%pi,40)';
y = sin(x);
yp = sin(x) + 0.1*rand(x,"normal");
xbasc()
plot2d(x, [yp y], style=[-2 2], leg="y=sin(x)+perturbation@y=sin(x)")
Rysunek 4.3: dessin en trait plain et avec des symboles non reliés tutu
3.
Okre±lanie skali Oto przykªad gdzie niezb¦dne jest narzucenie skali izometrycznej tutu
bowiem chcemy narysowa¢ okr¡g (patrz rysunek (4.4)).
postaci
frameflag=val,
gdzie
val
Dodatkowy parametr b¦dzie
powinna przyj¡¢ warto±¢ 4 aby otrzyma¢ skale izome-
tryczn¡ (dobran¡ na podstawie warto±ci minimalnej i naksymalnej)
3
tutu
68
t = linspace(0,2*%pi,60)';
x1 = 2*cos(t); y1 = sin(t);
// elipsa
x2 = cos(t); y2 = y1;
// okr\k{a}g
x3 = linspace(-2,2,60)'; y3 = erf(x3); // funkcja b\l{}\k{e}du
legenda = "elipsa@okr\k{a}g@funkcja b\l{}\k{e}du"
plot2d([x1 x2 x3],[y1 y2 y3],style=[1 2 3], frameflag=4, leg=legenda)
xtitle("Znowu krzywe...","x","y")
Rysunek 4.4: Elipsa, okr¡g i funkcja bª¦du
W pewnych przypadkach
frameflag towarzyszy¢ powinien parametr rect.
Je±li na przykªad
chcemy samodzielnie okre±li¢ obszar rysowania (zwalniaj¡c z tego punkcj¦
musimy napisa¢
plot2d
tutu)
rect = [xmin ; ymin ; xmax ; ymax ] w poª¡czeniu z frameflag=1 jak w przykªadzie
poni»ej
x = linspace(-5,5,200)';
y = 1 ./(1 + x.^2);
xbasc()
plot2d(x, y, frameflag=1, rect=[-6,0,6,1.1])
xtitle("Funkcja Rungego tutu")
Oto wszystkie mo»liwe warto±ci dla
frameflag=0
frameflag=1
frameflag=2
frameflag=3
frameflag=4
frameflag=5
frameflag=6
frameflag=7
frameflag=8
Uwaga:
frameflag
u»ycie wcze±niej zdeniowanej skali (lub domy±lnej)
skala zadana przez kwadrat
skala obliczona jako maksimum i minimum z Mx i My
échelle isométrique calculée en fonction de rect tutu
skala izometryczna obliczona jako maksimum i minimum z Mx et My
identycznie 1 ale z ewntualnym dostosowaniem graduation tutu
identycznie 2 mais avec adaptation eventuelle pour la graduation
identycznie 1 ale wcze±niejsze krzywe s¡ odrysowywane
identycznie 2 ale wcze±niejsze krzywe s¡ odrysowywane
W przypadkach 4 i 5 mo»e zaj±¢ (ewentualna) modykacja obszaru rysowania w
taki sposób aby stopniowanie (tutu) (które jest zawsze tutu) tutu (tak zwane tutu).
4.
Precyzowanie umieszczenis osi Rozmieszczenie osi mo»emy okre±la¢ pisz¡c axesflag=val.
W kolenym przykªadzie (patrz rysunek (4.5))
przetna si¦ wpunkcie
(0; 0)
val
ma warto±¢ 5 co powoduje, »e osie
4 bez tutu boite englobante :
x = linspace(-14,14,300)';
y = sinc(x);
xbasc()
plot2d(x, y, style=2, axesflag=5)
xtitle("Funkcja sinc")
Rysunek 4.5: Umieszczenie osi otrzymane dla
Oto tabela podaj¡ca wszytkie mo»liwo±ci:
4
Gdy punkt (0; 0) jest we wn¦trzu obszaru rysowania.
69
axesflag=5
bez pudeªka, osi oraz jednostek
z pudeªkiem, osiami i jednostkami (x na dole, y po lewej)
z pudelkiem, ale bez osi i jednostek
z pudeªkiem, osiami i jednostkami (x na dole, y po lewej)
bez pudeªka, ale z osiami i jednostkami (punkt przeci¦cia w ±rodku)
bez pudeªka, ale z osiami i jednostkami (punkt przeci¦cia dla x = 0 i y = 0)
axesflag=0
axesflag=1
axesflag=2
axesflag=3
axesflag=4
axesflag=5
5.
Skala logarytmiczna Odpowiedni parametr jest postaci
logflag=str,
gdzie
str
jest
ªañcuchem zªo»onym z dówch znaków pierwszy dotyczy osi OX, drugi OY i ka»dy przyjmuje warto±¢
n
(nie logarytmiczna) lub
l
(logarytmiczna).
x = logspace(0,4,200)';
y = 1 ./x;
xbasc()
subplot(1,2,1)
plot2d(x, y, style=2, logflag= "ln")
xtitle("logflag=""ln""")
subplot(1,2,2)
plot2d(x, y, style=2, logflag= "ll")
xtitle("logflag=""ll""")
Rysunek 4.6: Wykorzystanie parametru
logflag
subplot(m,n,num) w jednym oknie
m informuje o podziale okna w pionie na
m równych cz¦±ci, n decyduje o podziale w poziomie num jest natomiast kolejnym numerem
Przykªad ten pokazuje tak»e jak przy pomocy funkcji
umie±ci¢ kilka (niezale»nych) wykresów. Parametr
okna spo±ród
mn
okien. Okna numerowane s¡ od lewej do prawej i od góry do doªu
poczynaj¡c od numeru 1.
St¡d okno na pozycji
(i; j )
ma numer
5
n (i
1) + j .
Nic
nie stoi na przeszkodzie aby modykowa¢ siatk¦ tutu celem dobranie najbardziej nam
odpowiadaj¡cego ukªadu wykresów. Na przykªad
xbasc()
subplot(1,2,1)
titlepage("po lewej")
subplot(3,2,2)
titlepage(["po prawej";"powy\.zej"])
subplot(3,2,4)
titlepage(["po prawej";"w centrum"])
subplot(3,2,6)
titlepage(["po prawej";"poni\.zej"])
xselect()
tutu okna w pionie na dwie cz¦±ci (lew¡ i praw¡), okna po prawej podzielono w poziomie na
trzy cz¦sci. Funkcj¦
subplot mo»na rozumie¢ jako dyrektyw¦ pozwalaj¡c¡ wybra¢ pewien
podobszar okna gracznego.
6.
Sªowo kluczowe
strf
frameflag i axesflag oraz, ze
plot2d zawiera tak»e ag¦ okre±la-
Pozwala ono zast¡pi¢ zarazem
wzgl¦du na kompatybilno±¢ z wcze±niejszymi wersjami
j¡c¡ czy ma ono zastosowanie do legendy, czy nie tutu. Podawana warto±¢ skªada si¦ z
trzech znaków
xyz,
gdzie
x równe 0 (nie ma legendy) lub 1 (legenda tworzona jest przez podanie
5
A nie
m
(i
1) + j jak napisane jest w pomocy!
70
leg=val) ;
frameag ;
cyfra od 0 do 5, odpowiadaj¡ca warto±ci podawanej w axesag.
y cyfra od 0 do 9, odpowiadaj¡ca warto±ci podawanej w
z
En fait il faut savoir l'utiliser car les séquences optionnelles de nombreuses primitives de
dessin ne disposent pas encore des mots clés
frameflag i axesflag
tutu. Dodatkowo jest
to bardzo praktyczne je±li chcemy doda¢ nowy wykres do ju» istniej¡cego bez zmieniania skali i ramki co mo»na osi¡gna¢ pisz¡c
frameflag=0, axesflag=0).
4.4
Inne wersje
(unikaj¡c w ten sposób pisania
plot2d: plot2d2, plot2d3
Zasadniczo u»ywa si¦ ich jak
1.
strf="000"
plot2d
taka sama skªadnia, takie same argumenty opcjonalne.
plot2d2 tutu pozwala narysowa¢ funkcj¦ w oparciu o skalary: w miejsce wykresu prostego
odcinka wprowadzamy punkty
do
(xi+1 ; yi ))
(xi ; yi ) et (xi+1 ; yi+1 ), plot2d2 odcinek poziomy (od (xi ; yi )
(xi+1 ; yi ) do (xi+1 ; yi+1 )). Oto przykªad
a nast¦pnie odcinek pionowy (od
(porównaj rysunek (4.7)):
n = 10;
x = (0:n)';
y = x;
xbasc()
plot2d2(x,y, style=2, frameflag=5, rect=[0,-1,n+1,n+1])
xtitle("plot2d2")
Rysunek 4.7: Wykorzystanie
2.
plot2d2
plot2d3 Rysuje diagram tutu batonow: dla ka»dego punktu
segment pionowy od
(xi ; yi ) plot2d3 rysuje jeden
(xi ; 0) do (xi ; yi ) (porównaj rysunek (4.8)) :
n = 6;
x = (0:n)';
y = binomial(0.5,n)';
xbasc()
plot2d3(x,y, style=2, frameflag=5, rect=[-1,0,n+1,0.32])
xtitle("Prawdopodobienstwo dla prawa binomialnego tutu B(6,1/2)")
Rysunek 4.8: Wykorzystanie plot2d3
4.5
Rysowanie wi¦kszej ilo±ci krzywych zªo»onych z ró»nej ilo±ci
punktów
Za pomoc¡
plot2d
i jego wariantów nie mo»na narysowa¢ za jednym razem wi¦kszej ilo±ci
krzywych, które nie s¡ dyskretyzowane na takiej samej ilo±ci przedziaªów (i chyba takich
samych przedziaªów tutu) co poci¡ga za soba konieczno±¢ kilkakrotnego u»ycia tej funkcji. Od
wersji 2.6 mo»na oby¢ si¦ bez podawania skali bez obawy o przykre niespodzianki, poniewa»
domy±lnie (frameflag=8) wcze±niejsze krzywe s¡ odrysowywane w przypadku zmiany skali.
Dlatego je±li kto± chce opanowa¢ skal¦ (chodzi tutaj chyba o to aby nie byla ona zmieniana
71
automatycznie tutu), musi to zrobic przy pierwszym wywoªaniu a dla nast¦pnych u»ywa¢
frameflag=06 .
Oto odpowiedni przykªad (porównaj rysunek (4.9))
x1 = linspace(0,1,61)';
x2 = linspace(0,1,31)';
x3 = linspace(0.1,0.9,12)';
y1 = x1.*(1-x1).*cos(2*%pi*x1);
y2 = x2.*(1-x2);
y3 = x3.*(1-x3) + 0.1*(rand(x3)-0.5); // identyczne jak y2, ale z zaburzeniem
ymin = min([y1 ; y2 ; y3]); ymax = max([y1 ; y2 ; y3]);
dy = (ymax - ymin)*0.05;
// aby doda\'c margines tutu
rect = [0,ymin - dy,1,ymax+dy]; // okno wykresu
xbasc()
// wyczyszczenie poprzednich wykresów
plot2d(x1, y1, style=1, frameflag=5, rect=rect) // 1-sze wywo\l{}anie, które ustali sk
plot2d(x2, y2, style=2, frameflag=0)
// 2-ie i 3-ie wywo\l{}anie;
plot2d(x3, y3, style=-1,frameflag=0)
// u\.zywamy poprzedniej skali
xtitle("Krzywe...","x","y")
Uwaga:
Wypróuj ten przykªad pisz¡c
frameflag=1
w miejsce
frameflag=5.
Nie mo»na mie¢
Rysunek 4.9: Jeszcze krzywe...
osobnej legendy dla ka»dej krzywej niemniej jest to mo»liwe do osi¡gni¦cia przy pomocy
niewielkiej ilo±ci progamowania.
4.6
Zabawa z kontekstem gracznym
moze lepiej praca? :))) Je±li wyprobowali±my poprzednie przykªady bez w¡tpienia i z ochot¡
b¦dziemy chcieli modykowa¢ niekóre rzeczy jak rozmiar symboli, rozmiar czy styl u»tego
fontu lub te» grubo±¢ strzaªek.
1.
Fonty : Aby zmieni¢ font nale»y u»y¢ poni»szego wywoªania
xset("font",font_id,fontsize_id)
gdzie
font_id
i
fontsize_id
s¡ liczbami caªkowitymi odpowiadaj¡cymi odpowiednio z
rodzaj i wielko±¢ wybranego fontu. Bie»¡cy font mo»na otrzyma¢ pisz¡c
f=xget("font")
gdzie
f
jest wektorem,
f(1)
f(2) jego wielko±¢. Mo»na prosxset("font size",size_id) i fontsize_id = xget("fon
opisuje rodzaj fontu a
tozmienia¢/uzyska¢ wielko±¢ za pomoc¡
Oto te, które s¡ teraz dost¦pne
Nazwa fontu
Identykator
Courier
0
Symbol
1
Wielko±¢
Identykator
8 pts
0
Times
2
Times-Italic
3
10 pts
1
12 pts
2
Times-Bold
4
14 pts
3
18 pts
4
Times-Bold-Italic
5
24 pts
5
Uwagi:
6
Courier est à chasse xe tutu;
font Symbol pozwala na u»ycie liter greckich (p odpowiada
Metoda ta jest konieczna je±li u»ywamy skali iso-metrycznej.
72
, a , etc...);
2.
Times jest fontem domy±lnym a jego domy±lny rozmiar to 10 punktów.
rozmiar symboli: zmieniamy poleceniem
xset("mark size",marksize_id)
bie»¡cy otrzymujemy natomiast pisz¡c
marksize_id = xget("mark size")
gdzie podobnie jak dla fontów rozmiar okre±lamy za pomoca cyfr od 0 do 5; 0 jest wielko±ci¡
domy±ln¡.
3.
grubo±¢ linii: zmieniamy / otrzymujemy pisz¡c
xset("thickness",thickness_id)
thickness_id = xget("thickness")
Grubo±¢ jest wielko±ci¡ dodatni¡ odpowiadaj¡c¡ liczbie pikseli (na grubo±¢) jak¡ ma mie¢
krzywa.
Dokonuj¡c zmiany grubo±ci kre±lonych linii wpªywamy tak»e, czy tego chcemy
czy nie, na grubo±¢ kre±lonej ramki i skali na osiach.
Wyj±ciem w takiej sytuacji jest
dwukrotne tworzenie rysunku. Za pierwszym razem pomijamy ramk¦ i skal¦ (axesflag=0).
Nast¦pnie powracamy do normalnej grubo±ci i nie zmieniaj¡c skali widocznego obszaru
(frameflag=0) rysujemy co± poza nim (na przykªad krzyw¡ zredukowana do jednego
punktu (
1; 1)):
xset("thickness", 3)
plot2d(x, y, axesflag=0, ...)
xset("thickness", 1)
plot2d(-%inf, -%inf, frameflag=0, ...)
Zatem drugie wywoªanie sªu»y jedynie do narysowania ramki i skali.
4.7
Tworzenie histogramów
Odpowiednia do tego celu funkcja scilaba nazywa si¦
histplot a jej wywoªanie jest nast¦puj¡ce
histplot(n, X, <,opt_arg>*)
gdzie
n
1.
2.
ni < ni+1 ):
w przypadku gdy n jest wektorem liniowym dane dzielone s¡ na k klas Ci = [ni ; ni+1 [
(wektor n ma wi¦c k + 1 skªadowych);
w przypadku gdy n jest liczb¡ caªkowit¡, dane dzielone s¡ na n równoodlegªych klas
8
< c1 = min(X ); cn+1 = max(X )
C1 = [c1 ; c2 ]; Ci =]ci ; ci+1 ]; i = 2; :::; n; avec ci+1 = ci + C
: C = (c
n+1 c1 )=n
jest albo liczb¡ caªkowit¡ albo wektorem liniowym (w którym
X wektor (liniowy lub kolumnowy) z danymi;
<,opt_arg>* ci¡g opcjonalnych argumentów jak dla plot2d z dodatkow¡ kombinacj¡ nor-
malization = val gdzie val jest staª¡ (zmienn¡ lub wyra»eniem) boolowskim (domy±lnie
true). Kiedy histogram jest znormalizowany, tutu son intégrale vaut 1 et approche donc une
densité (dans le cas contraire, la valeur d'une plage correspond au nombre de composantes
de
X
tombant dans cette plage).
spondant à l'intervalle
:
(
Plus précisemment, la plage de l'histogramme corre-
Ci vaut donc (m étant le nombre de données, et Ci = ni+1 ni )
fXj 2Ci g
mCi
card fXj 2 Ci g
card
73
normalization = vrai
si normalization = faux
si
Poni»ej przedstawiamy maªy przykªad, tutu toujours avec la loi normale (patrz rysunek (4.10))
:
X = rand(100000,1,"normal"); classes = linspace(-5,5,21);
histplot(classes,X)
// tutu on lui superpose le tracé de la densité de N(0,1)
x = linspace(-5,5,60)'; y = exp(-x.^2/2)/sqrt(2*%pi);
plot2d(x,y, style=2, frameflag=0, axesflag=0)
Rysunek 4.10: Histogram próbki liczb losowych wybranych z rozkªadem
4.8
Zapisywanie graki w ró»nych formatach
W celu zachowanie utworzonego rysunku wybieramy z menu
Export
File
okna gracznego opcj¦
a nast¦pnie wybieramy po»¡dany format. tutu - sprawdzi¢ to Wi¦kszo±¢ z nich opiera
si¦ na postscripcie...
pliku typu
4.9
N (0; 1) tutu
.
Pocz¡wszy od wersji 2.5 mamy tak»e mo»liwo±¢ eksportu graki do
gif.
Prosta animacja
Realizacja animacji przy pomocy Scilaba jest do±¢ prosta, jako »e pozwala on na podwójne
buforowanie dzi¦ki czemu unikamy efektu migotania, gdy» wykres tworzony jest w ukryciu
i dopiero potem pokazywany.
7
Mamy do wyboru dwa drivery maj¡ce wpªyw na tworzenie
wykresu na ekranie
Rec, który powoduje, »e wszystkie operacje graczne zwi¡zane s¡ z oknem; jest to domy±lny
drvier;
X11,
tutu qui se contente simplement d'acher les graphiques (il est alors imposible de
zoomer).
Do celów tworzenia animacji najcz¦sciej odpowiedni b¦dzie ten ostatni; wybieramy go pisz¡c
driver("X11")
(w celu powrócenia do drivera domy±lnego piszemy
driver(›ec")).
Przy podwójnym buforowaniu ka»dy kolejny obraz tworzony jest najpierw w pami¦ci (powstaje
wówczas tak zwana pixmapa) a dopiero póŸniej przenoszony na ekran. Oto prosty schemat
post¦powania przy tworzeniu animacji
driver("X11")
// tutu pas d'enregistrement des opérations graphiques
xset("pixmap",1)
// przej\'scie do trybu podwójnego buforowania
...........
// ewentualne instrukcje ustalaj\k{a}ce skal\k{e}
for i=1:nb_dessins
xset("wwpc")
// wyczyszczenie pixmapy
.......
.......
// tworzenie i-tego rysunku
.......
xset("wshow")
// przeniesienie rysunku na ekran
end
xset("pixmap",0)
// powrót do bezpo\'sredniego tworzenia rysunków na ekranie
driver("Rec")
// przej\'scie do domy\'slego drivera
7
Oprócz driverów pozwalaj¡cych tworzy¢ rysunki jako
postscript, fig
74
czy
gif.
Uwaga:
W powy»szym post¦powaniu czyszczenie caªego obszaru rysowania przy pomocy
xset("wwpc")nie czynno±ci¡ wymagan¡.
Zamiast tego mo»na u»y¢ na przykªad funkcji
xclea,
co uchroni nas przed ka»dorazowym odrysowywaniem tych obszarów rysunku, które si¦ nie
zmieniaj¡. Aby tutu u»y¢ technik maskowania nale»y za pomoc¡ wywoªanie
zmieni¢ funkcj¦ steruj¡c¡ wy±wietlaniem (gdzie
num
xset('alufunction',num)
to liczba caªkowita zwi¡zana z wybran¡
funkcj¡); patrz Help i przykªady.
Poni»ej przedstawiony zostanie przykªad animacji: poruszaj¡cy si¦ ±rodek ci¦»ko±ci prostok¡ta
(o dªugo±ci
L
i szeroko±ci
l)
po okr¦gu o promieniu
r
i ±rodku w punkcie
(0; 0);
prostok¡t
dodatkowo obraca si¦ wokóª swojego ±rodka ci¦»ko±ci. tutu Il y a certain un nombre de détails
qui se greent autour du canevas général exposé ci-avant :
l'ordre
plot2d
sert uniquement à régler l'échelle (isométrique) pour les dessins ;
xset("background",1) impose la couleur 1 (du noir dans la carte des couleurs par défaut)
comme couleur d'arrière plan, mais il est recommandé d'exécuter l'instruction xbasr()
pour mettre eectivement à jour la couleur du fond ;
xfpoly suivi de xpoly pour dessiner
xset("thickness",3)) ; à chaque fois
xset(¢olor",num) ;
le dessin consiste à appeler la fonction
le bord (avec
ici 3 pixels ce qui est obtenu avec
on change la
couleur à utiliser avec
l'instruction
xset("default")
repositionne le contexte graphique de la fen¦tre à des
valeurs par défaut ; ainsi la variable
1,
background
pixmap
reprend la valeur 0,
thickness
la valeur
sa valeur par défaut, etc...
n = 4000;
L = 0.6; l = 0.3; r = 0.7;
nb_tours = 4;
t = linspace(0,nb_tours*2*%pi,n)';
xg = r*cos(t); yg = r*sin(t);
xy = [-L/2 L/2 L/2 -L/2;... // 4 punkty graniczne
-l/2 -l/2 l/2 l/2];
xselect()
driver("X11")
xset("pixmap",1)
plot2d(\%inf,\%inf, frameflag=3, rect=[-1,-1,1,1], axesflag=0)
xset("background",1); // czarne t\l{}o
xbasr()
// tutu utile pour la mise a jour du background
xset("thickness",3) // zwi\k{e}kszenie grubo\'sci kre\'slonych linii (3 pixele)
xset("font",2,4)
for i=1:n
xset("wwpc")
theta = 3*t(i);
xyr = [cos(theta) -sin(theta);...
sin(theta) cos(theta)]*xy;
xset("color",2)
xfpoly(xyr(1,:)+xg(i), xyr(2,:)+yg(i))
xset("color",5)
xpoly(xyr(1,:)+xg(i), xyr(2,:)+yg(i),"lines",1)
xset("color",32)
xtitle("Animation simple")
xset("wshow")
// przeniesienie pixmapy na ekran
end
driver("Rec")
// powrot do domy\'slnego drivera
xset("default")
// przywrócenie domy\'slnego kontekstu graficznego
75
4.10
Powierzchnie
Podstawow¡ funkcj¡ pozwalaj¡c¡ na tworzenie wykresów powierzchni jest
plot3d8 .
Przy
preprezentacji powierzchni za pomoca facettes tutu mamy mo»liwo±¢ okre±lenia innego koloru
dla ka»dej z nich. Od wersji 2.6 mo»na tak»e, zarówno dla fscettes trójk¡tnych jak i kwadratowych okre±li¢ kolor dla ka»dego z wierzchoªków, przez co rendu tutu otrzymywane jest przez
interpolacj¦ kolorów okre±lonych w wierzchoªkach.
4.10.1 Wprowadzenie do plot3d
Gdy powierzchnia opisane jest przez równanie typu
z = f (x; y),
j¡ narysowa¢ je±li argumenty s¡ z obszaru prostok¡tnego.
f (x; y) = cos(x)cos(y) dla (x; y) 2 [0; 2] [0; 2] :
szczególnie ªatwo mo»na
Jako przykªad rozwa»my funkcj¦
x=linspace(0,2*\%pi,31); // dyskretyzacja zmiennej x (a tak\.ze y : b\k{e}dzie to s
z=cos(x)'*cos(x);
// zbiór warto\'sci zmiennej z : macierz z(i,j) = f(x(i),y(
plot3d(x,x,z)
// rysunek
Rysunek 4.11: Funkcja
z = cos(x)cos(y)
9
W efekcie otrzymamy co± podobnego do rysunku (4.11) . W najbardziej ogólnej formie funkcji
plot3d
lub
plot3d1
u»ywamy pisz¡c
plot3d(x,y,z <,opt_arg>*)
plot3d1(x,y,z <,opt_arg>*)
gdzie dla
form¦
plot2d, <,opt_arg>*
sªowo_kluczowe=warto±¢.
ozancza ci¡g argumentów opcjonalnych,
W najprostszym przypadku,
x
i
y
opt_arg
przyjmuje
s¡ wektorami liniowymi
(1; nx) i (1; ny)) odpowiadaj¡cymi dyskretyzacji zmiennej x oraz y, natomiast z jest macierz¡
(nx; ny) tak¡, »e zi;j jest wysoko±ci¡ w punkcie (xi ; yj ).
(
Opcjonalne argumenty to:
1.
theta=val_theta i alpha=val_alpha to dwa k¡ty (w stopniach) okre±laj¡ce punkt widzenia
O jest ±rodkiem pudeªka englobante tutu, Oc kierunk= kt(Oz; Oc) i = kt(0x; Oc0 ) gdzie Oc0 jest rzutem Oc
we wspóªrz¦dnych sferycznych (je±li
iem patrzenia kamery, wówczas
na pªaszczyzn¦
2.
Oxy);
leg=val_leg pozwala okre±li¢ nazw¦ dla ka»ej z osi (na przykªad leg="x@y@z"), argument
efektywny val_leg jest ªañcuchem znakowym, w którym @ stanowi separator pomi¦dzy
nazwami;
3.
flag=val_ag gdzie val_ag jest wektorem o trzech skªadowych [mode type box] pozwalaj¡cym okre±li¢:
mode zwi¡zany jest z rysunkiem faces tutu i siatki:
10
dla mode > 0, faces niewidoczne s¡ usuwane , siatka pozostaje widoczna;
dla mode = 0, otrzymujemy tutu un rendu (fr. l de fer, ang. wireframe)
(a) parametr
i.
ii.
de la
surface;
iii. dla
8
9
plot3d1
mode < 0, faces niewidoczne s¡ usuwane a siatka nie jest rysowana.
u»ywana analogicznie pozwala uzale»ni¢ warto±¢ koloru od warto±ci przyjmowanej na osi OZ.
Dokªadnie rzecz bior¡c rysunek ten przedstawia efekt u»ycia funkcji
plot3d1
gdzie na potrzeby publikacji zamiast
kolorów u»yto odcieni szaro±ci a tak»e ustawiono troch¦ inny punkt widzenia.
10
tutu actuellement c'est l'algorithme du peintre qui est utilisé, c-a-d qu'un tri des facettes est eectué et les plus éloignées
de l'observateur sont dessinées en premier.
76
Dodatnio okre±lona strona face tutu (patrz dalej) b¦dzie malowana z wykorzystaniem
koloru numer
instrukcj¡
mode
za± strona przeciwna przy u»yciu koloru, który mo»emy okre±li¢
xset("hidden3d",colorid)
(domy±lnie jest to 4 kolor z palety).
type pozwala okre±li¢ skal¦:
type otrzymana skala
(b) parametr
0
u»ycie poprzedniej skali (tutu ou par défaut)
1
skala wraz z
2
skala otrzymana w oparciu o minimum i maximum zmiennych tutu
3
jak 1 ale skala jest izometryczna
4
jak 2 ale skala jest izometryczna
5
variante de 3
6
variante de 4
(c) parametr
4.
ebox
box kontroluje tutu le pourtour du graphe :
box otrzymany efekt
0
juste le dessin de la surface
2
osie pod powierzchnia s¡ rysowane
3
jak dla 2 z dodatkowym tutu la boite englobante
4
jak dla 3 z dodatkowym tutu la graduation des axes
ebox=val_ebox pozwala okre±li¢ tutu la boite englobante, val_ebox
[xmin ; xmax ; ymin ; ymax ; zmin ; zmax ].
jest wektorem o 6
skªadowych
Oto maªy przykªad, w którym u»ywa si¦ prawie wszystkich parametrów
plot3d.
Jest to prosta
animacja pozwalaj¡ca lepiej zrozumie¢ zmiane punktu widzenia przy pomocy parametrów
theta i alpha.
W skrypcie tym u»ywamy
flag=[2 4 4],
co oznacza
mode = 2 powierzchnia b¦dzie rysowana (jej dodatno okre±lona strona) kolorem 2 oraz
b¦dzie widoczna siatka;
type = 4
zostanie u»yta skala izometryczna obliczona na podstawie danych (jest to
równowa»ne wyborowi
type = 3 z parametrem ebox przyjmuj¡cym warto±ci równe mini-
mum i maksimum danych);
box = 4 rysunek b¦dzie zawieraª pudeªko tutu boite oraz stopniowanie et des graduations.
x=linspace(-%pi,%pi,31);
z=sin(x)'*sin(x);
n = 200;
theta = linspace(30,390,n); // pe\l{}ny obrót
alpha = [linspace(60,0,n/2) linspace(0,80,n/2)]; // od góry
// do do\l{}u
xselect()
xset("pixmap",1)
// aktywowanie podwójnego buforowania
driver("X11")
// zmieniamy parametr theta
for i=1:n
xset("wwpc") // wyczyszczenie bie\.z\k{a}cego bufora
plot3d(x,x,z,theta=theta(i),alpha=alpha(1),leg="x@y@z",flag=[2 4 4])
xtitle("zmiany punktu widzenia przy pomocy parametru theta")
xset("wshow")
end
// zmieniamy parametr alpha
for i=1:n
xset("wwpc") // wyczyszczenie bie\.z\k{a}cego bufora
plot3d(x,x,z,theta=theta(n),alpha=alpha(i),leg="x@y@z",flag=[2 4 4])
xtitle("zmiany punktu widzenia przy pomocy parametru alpha")
77
xset("wshow")
end
xset("pixmap",0)
driver("Rec")
4.10.2 Kolory
Powró¢my jeszcze na chwilk¦ do ostatniego przykªadu i zamiast
uzale»niaj¡c tym samym kolory od warto±ci zmiennej
z.
plot3d
napiszmy
plot3d1
Narysowana powierzchnia powinna
przypomina¢ w tym momencie mozaike gdy» wykorzystywana plaeta kolorów domy±lnie nie
jest ci¡gªa.
(nb_couleurs,3),
Paleta kolorów jest macierz¡ o wymiarze
gdzie i-ta linia deniuje intensy-
wno±ci skªadowej czerwonej (warto±¢ zawarta w przedziale od 0 do 1), zielonej i niebieskiej
dla i-tego koloru.
Maj¡c tak¡ macierz, któr¡ nazwiemy
C,
polecenie
xset(¢olormap",C)
pozwala j¡ wczyta¢ (zaªadowa¢) do kontekstu gracznego bie»¡cego okna gracznego. Funkcje,
hotcolormap
oraz
greycolormap
11 .
dostarczaj¡ mapy ze stopniow¡ zmian¡ kolorów
Maªa
uwaga: je±li dokonujemy zmiany palety kolorów po narysowaniu jakiego± rysunku, zmiany nie
b¦d¡ widoczne natychmiast (jest to zachowania normalne); wystarczy zmieni¢ rozmiar okna
lub tutu d'envoyer l'ordre
xbasr(numero_fenetre).
Oto nowy przykªad
x = linspace(0,2*%pi,31);
z = cos(x)'*cos(x);
C = hotcolormap(32); // hot colormap z 32 kolorami
xset("colormap",C)
xset("hidden3d",30) // wybór koloru 30 do rysowania po ujemnie okre\'slonej stroni
xbasc()
plot3d1(x,x,z, flag=[1 4 4]) // spróbuj tak\.ze z flag=[-1 4 4]
Uwaga : w
plot3d1,
wykorzystuje si¦ jedynie znak parametru
zostanie narysowana, nie zostanie za± gdy
mode < 0).
mode
(je±li
mode
0 siatka
4.10.3 plot3d z des facettes
Chc¡c u»y¢ tej funkcji w jak najogólniejszej postaci nale»y poda¢ opis powierzchni uwzgl¦dnia-
xf, yf, zf o wymiarze (nb_sommets_par_face, nb_faces), gdzie xf(j,i),yf(j,i),zf(j,i) s¡ wspóªrz¦dnymi
j¡c pojedyñczy tutu facettes. Okre±lany jest on przy pomocy 3 macierzy
j-tego wierzchoªka i-tego tutu facette. Poza tymi zmianami dalsze u»ycie jest takie samo jak
w poprzednich przykªadach:
plot3d(xf,yf,zf <,opt_arg>*)
Orientacja tutu facettes jest odmienna od zwyczajowo przyj¦tej (patrz rysunek (4.12).
Rysunek 4.12: orientacja tut facettes w Scilab-ie
W celu zdenowania kolorów dla ka»dego facette, trzeci argument musi by¢ list¡ :
gdzie
colors
jest wektorem o rozmiarze
nb_faces, colors(i)
list(zf,colors)
okre±lan numer (w palecie)
koloru i-tego tutu facette.
Jak w pierwszym przykªadzie, narysujemy ±ciany trój±cianu z rysunku (4.13), dla którego:
2 3
2 3
2 3
2 3
0
1
0
0
P1 = 4 0 5 ; P2 = 4 0 5 ; P3 = 4 1 5 ; P4 = 4 0 5 ;
0
11
Patrz tak»e sekcja
0
Contributions na stronie Scilab.
78
0
1
Rysunek 4.13: Trój±cian
gdzie denicja ±cian jest nast¦pujaca (w ten sposób otrzymujemy ±ciany zewn¦trzne z orientacj¡
dodatni¡ dla Scilab-a):
f1 = (P1 ; P2 ; P3 ); f2 = (P2 ; P4 ; P3 ); f3 = (P1 ; P3 ; P4 ); f4 = (P1 ; P4 ; P2 )
Napiszmy wi¦c:
//
f1 f2 f3 f4
xf = [ 0 1 0 0;
1 0 0 0;
0 0 0 1];
yf = [ 0 0 0 0;
0 0 1 0;
1 1 0 0];
zf = [ 0 0 0 0;
0 1 0 1;
0 0 1 0];
// tutu ouf !
xbasc()
plot3d(xf,yf,list(zf,2:5), flag=[1 4 4], leg="x@y@z",alpha=30, theta=230)
xselect()
Otrzymany efekt powinien przypomina¢ rysunek 4.14.
Mo»na zauwa»y¢, »e
plot3d
u»ywa
prostej tutu projection orthographique et non une projection perspective plus réaliste.
Rysunek 4.14: Trój±cian narysowany w Scilab-ie.
Na bie»¡ce potrzeby, obliczenia tutu des facettes, mog¡ by¢ efektywniejsze dzi¦ki funkcjom:
eval3dp i nf3d
genfac3d dla powierzchni deniowanych przy pomocy z
dla powierzchni zdeniowanych przy pomocy
z (u; v) (patrz 4.10.4) ;
x = x(u; v); y = y(u; v); z =
= f (x; y) (przykªad pokazany jest
troch¦ dalej (4.10.5)).
Je±li powierzchnia (wielo±cian) zdeniowana jest w taki sam sposób jak trój±cian z przykªadu
nie mo»na jego narysowa¢ bezpo±rednio przy u»yciu
plot3d.
W celu otrzymania opisu oczeki-
wanego przez Scilab-a mo»na wykorzysta¢ funkcj¦ podobn¡ do przedstawionej poni»ej:
function [xf,yf,zf] = facettes_polyedre(P)
// tutu transforme la structure Polyedre de l'exemple
// sur les tlist en description de facettes pour
// visualisation avec plot3d
[ns, nf] = size(P.face) // ns: ilo\'s\'c wierzcho\l{}ków tworz\k{a}cych \'scian\k{
// nf: ilo\'s\'c \'scian
xf=zeros(P.face); yf=zeros(P.face); zf=zeros(P.face)
for j=1:ns
num = connect(ns+1-j,:) // dla odwrócenia orientacji
xf(j,:) = P.coord(1, num)
yf(j,:) = P.coord(2, num)
79
zf(j,:) = P.coord(3, num)
end
endfunction
Maj¡c tak okre±lon¡ funkcj¦, rysunek wielo±cianu otrzymamy pisz¡c
[xf,yf,zf] = facettes_polyedre(Cube);
plot3d(xf,yf,list(zf,2:7), flag=[1 4 0],theta=50,alpha=60)
4.10.4 Rysowanie powierzchni opisanej przy pomocy x = x(u; v), y = y(u; v),
z = z (u; v)
OdpowiedŸ: wzi¡¢ dyskretyzacj¦ dziedziny parametrów obliczy¢ tutu les facettes przy pomocy
funkcji (eval3dp). Ze wzgl¦dów wydajno±ciowych, funkcja okre±laj¡ca parametry powierzchni
powinna by¢ napisana wektorowo.
Je±li
(u1 ; u2 ; : : : ; um ) i (v1 ; v2 ; : : : ; vn )
stanowi¡ dyskre-
tyzacj¦ dziedziny parametrów, funkcja powinna by¢ wywoªywana jednokrotnie z dwoma du»ymi
wektorami rozmiaru
m n:
U = (u| 1 ; u2 ;{z: : : ; um}; |u1 ; u2 ;{z: : : ; um}; : : : : : : ; |u1 ; u2 ;{z: : : ; um})
n
1
2
V = (v|1 ; v1{z
; : : : ; v}1 ; v|2 ; v2{z
; : : : ; v}2 ; : : : : : : ; |vn ; vn{z
; : : : ; vn})
m
fois
v1
m
fois
v2
m
fois
W oparciu o te dwa wektory, funkcja powinna tworzy¢ 3 wektory
takie, »e:
vn
X; Y
et
Z
wymiaru
mn
Xk = x(Uk ; Vk ); Yk = y(Uk ; Vk ); Zk = z (Uk ; Vk )
12 de façon à pouvoir ¦tre utilisée
Oto kilka przykªadów parametryzacji powierzchni, tutu écrite
avec
eval3dp
:
function [x,y,z] = tore(theta, phi)
// tutu paramétrisation classique d'un tore de rayons R et r et d'axe Oz
R = 1; r = 0.2
x = (R + r*cos(phi)).*cos(theta)
y = (R + r*cos(phi)).*sin(theta)
z = r*sin(phi)
endfunction
function [x,y,z] = helice_torique(theta, phi)
// tutu paramétrisation d'une helice torique
R = 1; r = 0.3
x = (R + r*cos(phi)).*cos(theta)
y = (R + r*cos(phi)).*sin(theta)
z = r*sin(phi) + 0.5*theta
endfunction
function [x,y,z] = moebius(theta, rho)
// wst\k{e}ga Moëbius-a
R = 1;
x = (R + rho.*sin(theta/2)).*cos(theta)
y = (R + rho.*sin(theta/2)).*sin(theta)
z = rho.*cos(theta/2)
endfunction
12
Piszemy je w naturalny sposób, pami¦taj¡c aby zamiast
*i/
80
napisa¢
.* i ./
i wszystko powinno dziaªa¢!
function [x,y,z] = tore_bossele(theta, phi)
// tutu paramétrisation d'un tore dont le petit rayon r est variable avec theta
R = 1; r = 0.2*(1+ 0.4*sin(8*theta))
x = (R + r.*cos(phi)).*cos(theta)
y = (R + r.*cos(phi)).*sin(theta)
z = r.*sin(phi)
endfunction
Oto przykªad wykorzystuj¡cy ostatni¡ powierzchni¦:
// skrypt rysuj\k{a}cy powierzchni\k{e} opisan\k{a} za pomoc\k{a} równania parametrycz
theta = linspace(0, 2*%pi, 160);
phi = linspace(0, -2*%pi, 20);
[xf, yf, zf] = eval3dp(tore_bossele, theta, phi); // tutu calcul des facettes
xbasc()
plot3d1(xf,yf,zf)
xselect()
Je±li chcemy u»y¢ kolorów a nie otrzymujemy ich na rysunku, spowodowane jest to niewªa±ciw¡ orientacj¡; wystarczy odwróci¢ kierunek jednego z wektorów stanowi¡cego dyskretyzacj¦
dziedziny.
Rysunek 4.15: Un tore bosselé... tutu
tutu Funkcja
nf3d
jest lekko podobna do
zdeniowa¢ soit-m¦me des matrices
X; Y; Z
eval3dp,
ale maj¡c dyskretyzacj¦
uiv
trzeba
tak¡, »e:
Xi;j = x(ui ; vj )
Yi;j = y(ui ; vj )
Zi;j = z (ui ; vj )
et vos facettes s'obtiennent alors avec
[xf,yf,zf] = nf3d(X,Y,Z).
Jako przykªad rozwa»my
wst¦g¦ Moëbius-a dénit juste avant :
nt = 120;
nr = 10;
rho = linspace(-0.5,0.5,nr);
theta = linspace(0,2*%pi,nt);
R = 1;
X = (R + rho'*sin(theta/2)).*(ones(nr,1)*cos(theta));
Y = (R + rho'*sin(theta/2)).*(ones(nr,1)*sin(theta));
Z = rho'*cos(theta/2);
[xf,yf,zf] = nf3d(X,Y,Z);
xbasc()
plot3d(xf,yf,zf, flag=[2 4 6], alpha=60, theta=50)
xselect()
Uwaga:
w celu otrzymania pawidªowej macierzy nale»aªo u»y¢ funkcji ones, tutu ce qui ne
rend pas le code très clair: funkcja eval3dp jest ªatwiejsza w u»yciu!
Rysunek 4.16: Wst¦ga Moëbius-a
81
4.10.5 plot3d z interpolacj¡ kolorów
Od wersji 2.6 , mo»liwe jest okre±lenie koloru dla ka»dego wierzchoªka tutu d'une facette.
colors takiego samego wymiaru jak xf, yf, zf daj¡c¡ opis
ka»dego facette, to znaczy tak¡, »e colors(i,j) jest kolorem zwi¡zanym z i-tym wierzchoªkiem
j-tego face, i poª¡czy¢ z trzecim argumentem (zf) w list¦:
Wystarczy okte±li¢ macierz
plot3d(xf,yf,list(zf,colors) <,opt_arg>*)
Oto przykªad pocz¡tkowy
plot3d
bez rysowania siatki:
tutu une couleur par face pour le dessin de gauche,
tutu une couleur par sommet pour celui de droite.
Aby obliczy¢ wartosci kolorów, wykorzystano pomcnicz¡ funkcj¦ wi¡»¡c¡ w sposób liniowy
dsearch dost¦pnej od wersji 2.7 ale mo»na
b¦dzie mo»na wykorzytanie funkcji genfac3d
warto±ci na karcie gracznej tutu!!!. (u»yto funkcji
ªatwo tutu vous en passer).
Zauwa»y¢ tak»e
pozwalaj¡cej na obliczenie tutu les facettes.
// przyk\l{}ad wykorzystania plot3d z interpolacj\k{a} kolorów
function [col] = associe_couleur(val)
// przypisanie koloru dla ka\.zdej z warto\'sci z val tutu przypsanie do warto\'sci?!!!
n1 = 1
// numer 1-ego koloru
n2 = xget("lastpattern") // numer ostatniego koloru
nb_col = n2 - n1 + 1
classes = linspace(min(val),max(val),nb_col)
col = dsearch(val, classes)
endfunction
x=linspace(0,2*\%pi,31);
z=cos(x)'*cos(x);
[xf,yf,zf] = genfac3d(x,x,z);
xset("colormap",graycolormap(64))
zmeanf = mean(zf,"r");
zcolf = associe_couleur(zmeanf);
zcols = associe_couleur(zf);
xbasc()
xset("font",6,2)
// font 6 (helvetica) tutu n'est disponible
// que dans la version cvs de scilab
subplot(1,2,1)
plot3d(xf,yf,list(zf,zcolf), flag=[-1 4 4])
xtitle("Jeden kolor na tutu face")
subplot(1,2,2)
plot3d(xf,yf,list(zf,zcols), flag=[-1 4 4])
xtitle("Jeden kolor na wierzcho\l{}ek")
xselect()
Rysunek 4.17: Z i bez interpolacji kolorów.
4.11
Krzywe w przestrzeni
Podstawow¡ funkcj¡ pozwalaj¡c¡ rysowa¢ krzywe w przestrzeni jest
przykªad tutu de l'hélice:
82
param3d.
Oto klasyczny
t = linspace(0,4*\%pi,100);
x = cos(t); y = sin(t) ; z = t;
param3d(x,y,z) // ewentualne wymazanie okna graficznego za pomoc\k{a} xbasc()
tutu mais comme cette dernière ne permet que d'achier une seule courbe nous allons nous
concentrer sur
param3d1
qui permet de faire plus de choses. Oto jej skªadnia:
param3d1(x,y,z <,opt_arg>*)
param3d1(x,y,list(z,colors) <,opt_arg>*)
Macierze
x, y
et
z
musz¡ by¢ tego samego wymiaru (np,nc) a ilo±¢ krzywych (nc) jest
okre±ªona przez ilo±¢ kolumn (jak dla
plot2d).
Parametry opcjonalne s¡ takie same jak dla
plot3d, modulo le fait que flag tutu ne ne comporte pas de paramètre mode.
colors jest wektorem okre±laj¡cym styl dla ka»dej krzywej (dokªadnie jak plot2d), to znaczy
gdy colors(i) jest warto±ci¡ caªkowit¡ dodatni¡, i-ta krzywa rysowana jest i-tym kolorem z
fnkcji
bie»¡cej palety kolorów (tutu ou avec diérents pointillés sur un terminal noir et blanc); je±li
za± zawarta jest pomi¦dzy -9 i 0, otrzymujemy rysnek zªo»ony z punktów (tutu non reliés)
zaznaczonych odpowiednim symbolem.
Oto przykªad, który powinien doprowadzi¢ nas do
rysunku (4.18):
t = linspace(0,4*\%pi,100)';
x1 = cos(t); y1 = sin(t) ; z1 = 0.1*t; // spirala
x2 = x1 + 0.1*(1-rand(x1));
y2 = y1 + 0.1*(1-rand(y1));
z2 = z1 + 0.1*(1-rand(z1));
xbasc();
xset("font",2,3)
param3d1([x1 x2],[y1 y2],list([z1 z2], [1,-9]), flag=[4 4])
xset("font",4,4)
xtitle("Spirala z per\l{}ami")
Rysunek 4.18: Krzywa i punkty w przestrzeni.
Jak dla
plot2d funkcj¦ t¡ nale»y wywoªa¢ kilkakrotnie je±li ró»ne krzywe nie maj¡ takiej samej
ilo±ci punktówon.
Oto skrypt, wyja±niaj¡cy jak utworzy¢ dwie grupy punktów ze ró»nymi
znakami i kolorami:
n = 50;
// ilo\'s\'c punktów
P = rand(n,3); // losowanie punktów
// tutu on impose les dimensions de la boite englobante
ebox = [0 1 0 1 0 1];
// rozdzielenie punktów na dwie grupy aby pokaza\'c jak przypisa\'c
// ró\.zne symbole i kolory do punktów
m = 30;
P1 = P(1:m,:) ; P2 = P(m+1:n,:);
// rysunek
xbasc()
// pierwsza grupa punktów
xset("color",2) // tutu du bleu avec la carte par defaut niebieski w domy\'slnej palecie (?
param3d1(P1(:,1),P1(:,2),list(P1(:,3), -9), alpha=60, theta=30,...
leg="x@y@z", flag=[3 4], ebox=ebox)
// tutu flag=[3 4] : 3 -> echelle iso se basant sur ebox
// tutu
4 -> boite + graduation
// druga grupa punktów
xset("color",5) // tutu du rouge avec la carte par defaut
param3d1(P2(:,1),P2(:,2),list(P2(:,3), -5), flag=[0 0])
83
// tutu -5 pour des triangles inverses
// tutu [0 0] : echelle fixée et cadre dessiné avec l'appel précédent
xset("color",1) // aby ustawi\'c czarny jako bie\.z\k{a}cy kolor
xtitle("Punkty...")
xselect()
4.12
Ró»no±ci
Istnieje jeszcze wiele prymitywów gracznych:
1.
contour2d i contour pozwalaj¡ rysowa¢ linie poziomicowe dla funkcji z
= f (x; y) okre±lonej
na prostok¡cie;
2.
grayplot i Sgrayplot
pozwalaj¡ reprezentowa¢ warto±ci funkcji tutu qui permettent de
représenter les valeurs d'une telle fonction en utilisant des couleurs ;
3.
fec
odgrywaja tak¡ sam¡ rol¦ jak dwie poprzednie dla funkcji okre±lonej tutu est dénie
sur une triangulation plane ;
4.
champ
pozwala okre±li¢ pole wektorowe w 2D ;
5. tutu wiele funkcji wywoªywanych w tym rozdziale dopuszcza ró»ne parametry aby tworzy¢
wykresy funkcji bardziej bezpo±rednio si on fournit une fonction scilab comme argument
(le nom de ces fonctions commence par un f
fchamp,...).
fplot2d, fcontour2d, fplot3d, fplot3d1,
13 wystarczy przejrze¢ tutu rubrique (dziaª,sekcja (?!))
Aby zda¢ sobie spraw¦ z mo»liwo±ci
Graphic Library pomocy.
Od wersji 2.7 istnieje nowy model graczny zorientowany obiektowo
pozwalaj¡cy modykowa¢ wªa±ciwo±ci graki po ujrzeniu rysunku.
Domy±lnie nie jest on
aktywny, ale je±li kto± chce poeksperymentowa¢ nale»y wyda¢ polecenie:
set("figure_style","new")
przed utworzeniem rysunku.
Jako »e ten nowy tryb jest w trakcie rozwijania zalecane jest
u»wanie wersji tutu cvs de scilab.
Biblioteka Enrico Ségré, któr¡ mo»na tutu ±ci¡gn¡¢ z jego strony:
http://www.weizmann.ac.il/~fesegre/
tutu complète celle de Scilab et contient takze funkcje pozwalaj¡ce upro±ci¢ tutu certaines
taches.
13
tutu attention risque de noyade !
84
Rozdziaª 5
Zastosowania i uzupeªnienia
Rozdziaª ten przedstawia metody rozwi¡zywania w Scilabie pewnych typów problemów analizy
numerycznej (aktualnie równa« ró»niczkowych...)
oraz dostarcza uzupeªnie«/dodatkowych
informacji niezb¦dnych podczas projektowania prostych symulacji stochastycznych.
5.1
Równania ró»niczkowe
Scilab dysponuje pot¦»nym interfejsem dla rozwi¡zywania numerycznego (w sposób przybli»ony) równa« ró»niczkowych przy zastosowaniu prostej instrucji
ode.
Rozwa»my zatem
nast¦puj¡ce równanie ró»niczkowe z warunkiem pocz¡tkowym :
0
u = f (t; u)
gdzie
u (t )
jest wektorem w
Rn, f
u(t0 ) = u0
jest funkcj¡
R Rn ! Rn, oraz u0 2 Rn.
Zakªadamy
warunki brzegowe dla których rozwi¡zanie istnieje i jest jednoznaczne a» do okresu
T.
5.1.1 Podstawowe u»ycie ode
Zdeniujmy funkcj
f
jako funkcj¦ Scilaba w nast¦puj¡cyj sposób :
function [f] = moja_funkcja(t,u)
//tutaj kod definiujacy f jako funkcje t i u.
endfunction
Rmq :
Podobnie, je±li równanie jest niezale»ne, nale»y mimo wszystko doprowadzi¢ równanie
do postaci w której mamy funkcj¦ zale»ne od zmiennej
Van der Pola :
kªad¡c
t.
Oto przykªad kodu dla równania
y00 = c(1 y2 )y0 y
u1 (t) = y(t) oraz u2 (t) = y0 (t) przeksztaªcamy je do ukªadu dwóch równa« ró»niczkowych
pierwaszego rz¦du :
d u 1 (t )
2 (t )
= uc(1
u21 (t))u2 (t) u1 (t)
dt u2 (t)
function [f] = VanDerPol(t,u)
// drugi skladnik dla rownania Van der Pol (c = 0.4)
f(1) = u(2)
f(2) = 0.4*(1 - u(1)^2)*u(2) - u(1)
endfunction
Nast¦pnie wywoªujemy
od
u0
ode aby rozwi¡za¢ równanie (ukªad równa«) wzgl¦dem t0 w T , wychodz¡c
(wektor kolumnowy) i chc¡c otrzyma¢ rozwi¡zanie w chwili
T , wpiszemy instrukcj¦ :
85
t(1) = t0 ; t(2); :::; t(m) =
t = linspace(t0,T,m);
[U] = ode(u0,t0,t,moja_funkcja)
Otrzymamy w ten sposób macierz
cz¦±ciowym
dla
t
ui (t(j ))
U o wymiarach (n; m), w której U(i,j) jest rozwi¡zaniem
(i-ta skªadowa w chwili
t(j )). Uwaga :
Liczba skªadowych branych
(czyli momenty w których otrzymuje si¦ rozwi¡zanie) nie maj¡ nic wspólnego z pre-
cyzj¡ oblicze«. Liczba skªadników jakie przyjmujemy dla
t (momenty, dla których obliczamy
rozwi¡zanie) nie ma wpªywu na precyzj¦ obliczen. Dokªadno±¢ oblicze« jest determinowana
przez inne parametry (maj¡ce warto±ci domy±lne). Z drugiej strony, oprócz
ode
istnieje wiele
innych algorytmów, które daj¡ si¦ zastosowa¢ do ró»nych sytuacji. Aby wybra¢ odpowiedni¡
metod¦ nale»y doda¢ odpowiedni parametr w trakcie wywoªania (patrz Help). Domy±lnie (tzn.
bez wybierania explicite jednej metody) stosowana jest metoda Adamsa predykcji, natomiast
1
w przypadku gdy Scilab okre±li równanie jako raide (sztywne) algorytm zostaje zmieniony
na metod¦ Gear-a.
Oto kompletny przykªad dla równania Van der Pola.
W tym przypadku przestrze« stanów
jest pªaska, mo»na zatem otrzyma¢ obraz dynamiki rysuj¡c pole wektorowe w prostok¡cie
[xmin ; xmax ] [ymin ; ymax ] za pomoc¡ instrukcji gracznej fchamp w nast¦puj¡cy sposób:
fchamp(moja_funkcja,t,x,y)
mojaf unkcjaoznaczanazwfunkcjiScilababdcskadnikiempoprawejstronierwnaniarnicz kowego; tjestmomentemwktrymchcemynaszkicowapole(wprzypadkucigymrwnaniamoemyprzyjdow
gdzie
// 1/ kreslimy pole wektorowe odpowiadajace rownaniu Van der Pola
n = 30;
delta = 5
x = linspace(-delta,delta,n); // tutaj y = x
xbasc()
fchamp(VanDerPol,0,x,x)
xselect()
// 2/ rozwiazujemy rownanie rozniczkowe
m = 500 ; T = 30 ;
t = linspace(0,T,m); // moment w ktorym znajduje sie rozwiazanie
u0 = [-2.5 ; 2.5];
// warunek poczatkowy
[u] = ode(u0, 0, t, VanDerPol);
plot2d(u(1,:)',u(2,:)',2,"000")
5.1.2 Van der Pol jeszcze raz
W tej cz¦±ci zwrócimy nasz¡ uwag¦ na mo»liwo±ci graczne Scilaba pozwalan¡ce otrzyma¢
wiele »¡danych trajektorii bez ponownego uruchamiania skryptu z inn¡ warto±ci¡ argumentu
u0 .
U»yjemy równie» skal¦ izometryczn¡ dla rysunków. Po wy±wietleniu pola wektorowego,
2
ka»dy warunek pocz¡tkowy b¦dzie zadany poprzez klikni¦cie lewym przyciskiem myszy ; pojawi si¦ wówczas punkt na »¡danej pozycji pocz¡tkowej. Jest to mo»liwe dzi¦ki funkcji
xclick,
której skªadnia jest nast¦puj¡ca :
[c_i,c_x,c_y]=xclick();
Jak wida¢, Scilab dyspinuje odpowiednimi procedurami, które umo»liwiaj¡ miedzy innymi
reagowanie na tzw zdarzenia graczne jak klikni¦cie mysz¡.
Kiedy takie zdarzenia ma
miejsce, nast¦puje automatczna lokalizacja pozycji punktu (w bie»¡cej skali) poprzez przypisanie jego wsp󪻦dnych do zmiennych
c_x
oraz
c_y.
Trzeci argument, czyli
odpowiedni klawisz myszy zgodnie z poni»sz¡ tabelk¡ :
1
2
równanie jest raide w przypadku gdy (mniej lub bardziej) ª¡czy si¦ z metodami jednoznacznymi
jak sugerowano w jednym z artykuªów dotycz¡cych Scilaba, zamieszczonym w Linux Magazine
86
c_i
oznacza
warto±¢ dla
c_i
klawisz
0
lewy
1
±rodkowy
2
prawy
W skrypcie wyko»ystano klikni¦cie na lewy klawisz myszy jako ten, wyznaczaj¡cy punkt
pocz¡tkowy dla p¦ku zdarze«.
couleur pozwala
u»yjemy fchamp do-
Na koniec nadano ka»dej z wyrysowanych trajektorii inny kolor (tablica
wybra¢ jeden z dost¦pnych kolorów). Aby otrzyma¢ skal¦ izometryczn¡
daj¡c opcjonalny argument jak dla
frameag i axesag
plot2d (nale»y u»y¢ strf=wartosc_strf jako »e parametry
nie s¡ akceptowane). Ostatni aspekt : aby zaznaczy¢ punkt pocz¡tkowy
obrysowano go maªym kóªkiem, natomiast aby pokaza¢ wszystkie mo»liwo±ci okna gracznego
wyko»ystano sze±cienny ukªad wspóªrz¦dnych. Ostatnia uwaga : podczas gdy jest wy±wietlone pole wektorowe, mo»na maksymalizowa¢ okno graczne! Klikaj¡c dwukrotnie otrzymano
rysunek (5.1) wszystkie trajektorie zbiegaj¡ do jednej sfery, czego sie spodziewamy, z puktu
widzenia teoretycznego dla tego równania
// 1/ wykres pola wektorowego dla rownania Van der Pola
n = 30;
delta_x = 6
delta_y = 4
x = linspace(-delta_x,delta_x,n);
y = linspace(-delta_y,delta_y,n);
xbasc()
fchamp(VanDerPol,0,x,y, strf="041")
xselect()
// 2/ rozwiazanie rownania rozniczkowego
m = 500 ; T = 30 ;
t = linspace(0,T,m);
couleurs = [21 2 3 4 5 6 19 28 32 9 13 22 18 21 12 30 27] // 17 kolorow
num = -1
while %t
[c_i,c_x,c_y]=xclick();
if c_i == 0 then
plot2d(c_x, c_y, style=-9, strf="000") // male o aby zaznaczyc C.I.
u0 = [c_x;c_y];
[u] = ode(u0, 0, t, VanDerPol);
num = modulo(num+1,length(couleurs));
plot2d(u(1,:)',u(2,:)', style=couleurs(num+1), strf="000")
elseif c_i == 2 then
break
end
end
Rysunek 5.1: Niektóre trajektorie w przestrzeni fazowej dla równania Van der Pol-a
5.1.3 Troche wi¦cej o ode
W tym drugim przykªadzie u»yjemy funkcji
ode z drugim czªonem, który przyjmuje dodatkowy
parametr oraz ustalimy sami tolerancj¦ dla kroku czasowego podczas rozwi¡zywania.
87
Oto
nasze nowe równanie ró»niczkowe (
Równanie Brusselator) :
du1
dt
du2
dt
= 2 (6 + )u1 + u21 x2
= (5 + )u1 u21 u2
które przyjmuje jako punkt krytyczny Pstat = (2; (5 + )=2). Poniewa» warto±ci parametru
zmieniaj¡ si¦ z ujemnej na dodatni¡, punkt stacjonarny zmienia swój charakter (jest staªy
lub zmienny, wchodz¡c, dla = 0 w zjawisko rozgaª¦zienia Hopf). Interesuj¡ nas trajektorie z
warunkiemi pocz¡tkowymi z s¡siedztwa tego punktu. Oto funkcja licz¡ca to równanie :
function [f] = Brusselator(t,u,eps)
//
f(1) = 2 - (6+eps)*u(1) + u(1)^2*u(2)
f(2) = (5+eps)*u(1) - u(1)^2*u(2)
endfunction
Aby poda¢ parametr, zast¡pimy w wywoªaniu
ode
nazw¦ funkcji (tutaj Brusselator) przez
uporz¡dkowan¡ list¦ zawieraj¡c¡ nazw¦ funkcji oraz jej parametry :
[x] = ode(x0,t0,t,list(moja_funkcja, par1, par2, ...))
W naszym przypadku :
[x] = ode(x0,t0,t,list(Brusselator, eps))
a nast¦pnie zastosujemy
fchamp
aby narysowa¢ pole.
Aby ustali¢ zakres tolerancji dla bª¦du lokalnego rozwi¡zania u»yjemy dodatkowych parametrów
rtol
oraz
trami.
atol
zaraz po nazwie funckji (lub listy zawieraj¡cej t¦ funkcj¦ wraz z jej parame-
W ka»dym kroku czasowym,
e (tzn.
v(tk 1 ) = U (tk 1 )) :
bª¦du lokalnego
tk 1
! tk = tk 1 + tk ,
obliczane jest oszacowanie
bª¦du dla kroku czasowego wychodz¡c z warunku pocz¡tkowego
e (t k ) ' U (t k )
Z
tk
tk 1
f (t; v(t))dt + U (tk 1 )
!
(drugi skªadnik jest rozwi¡zaniem dokªadnym zale»nym od rozwi¡zania mumerycznego
U (tk 1 )
otrzymanego w poprzednim kroku) a nast¦pnie sprawdza czy zawiera si¦ on w zakresie tolerancji formuowane za pomoc¡ dwóch parametrów
rtol
et
atol
:
toli = rtoli jUi (tk )j + atoli ; 1 i n
w przypadku gdy dane s¡ dwa wektory dªugo±ci
n dla tych praramertów, oraz:
toli = rtol jUi (tk )j + atol; 1 i n
gdy dane s¡ skalary. Je»eli
jei(tk )j toli dla wszystkich skªadowych tk , krok jest akceptowany
a nast¦pnie obliczony zostaje nowy krok czasowy w taki sposób, »e kryterium naªo»one na
przyszªy bª¡d b¦dzie miaªo pewne szanse na zrealizowanie si¦. W przeciwnym razie, ponownie
caªkuje si¦ pocz¡wszy od
t( k 1) przyjmuj¡c nowy, nieco mniejszy krok czasowy (obliczony wg
zasady, »e przyszªy test bª¦du lokalnego b¦dzie równie» speªniony z silnym prawdopodobie«stwem). Metody tego typu oprócz zmiennych post¦pu czasowgo, manipuluj¡ równie» kolejno±ci¡
równa« w celu otrzymania dobrej wydajno±ci informacji... Domy±lnie stosowanymi warto±ciami s¡
rtol = 10 5 i atol = 10 7 (za wyj¡tkiem typów wybieraj¡cych metod¦ Runge Kutta).
Wa»na uwaga : caªkowanie mo»e cz¦sto sie nie powi¹¢...
Poni»ej przedstawiamy przykªadowy skrypt, w którym punkty krytyczne oznaczono maªymi,
czarnymi kwadratami (otrzymano je przy pomocy prostej funkcji gracznej
88
xfrect)
:
// Brusselator
eps = -4
P_stat = [2 ; (5+eps)/2];
// granice dla wykresu pola wektorowego
delta_x = 6; delta_y = 4;
x_min = P_stat(1) - delta_x; x_max = P_stat(1) + delta_x;
y_min = P_stat(2) - delta_y; y_max = P_stat(2) + delta_y;
n = 20;
x = linspace(x_min, x_max, n);
y = linspace(y_min, y_max, n);
// 1/ wykres pola wektorowego
xbasc()
fchamp(list(Brusselator,eps),0,x,y, strf="041")
xfrect(P_stat(1)-0.08,P_stat(2)+0.08,0.16,0.16) // dla zaznaczenia punktow krytycznych
xselect()
// 2/ rozwiazanie rownania rozniczkowego
m = 500 ; T = 5 ;
rtol = 1.d-09; atol = 1.d-10; // zakres tolerancji bledu
t = linspace(0,T,m);
couleurs = [21 2 3 4 5 6 19 28 32 9 13 22 18 21 12 30 27]
num = -1
while %t
[c_i,c_x,c_y]=xclick();
if c_i == 0 then
plot2d(c_x, c_y, style=-9, strf="000") // male o aby zanaczyc C.I.
u0 = [c_x;c_y];
[u] = ode(u0, 0, t, rtol, atol, list(Brusselator,eps));
num = modulo(num+1,length(couleurs));
plot2d(u(1,:)',u(2,:)', style=couleurs(num+1), strf="000")
elseif c_i == 2 then
break
end
end
Rysunek 5.2: Niektóre trajektorie w polu fazowym dla Brusselatora (
5.2
= 4)
Generownie liczb losowych
5.2.1 Funkcja rand
Do tej pory funkcja ta sªu»yªa nam gªównie do wypeªniania liczbami losowymi naszych macierzy
i wektorów... Funkcja ta u»ywa liniowego generatora nast¦puj¡co
Xn+1 = f (Xn ) = (aXn + c) mod m; n 0;
Jej okres jest z pewno±ci¡ równy
[0; m 1].)
m (oznacza to, »e f
gdzie
3 :
8
< m = 231
843314861
: ac == 453816693
jest permutacj¡ cykliczn¡ na przedziale
Zauwa»my, »e wszystkie generatory liczb losowych w komputerze s¡ ci¡gami ideal-
nie zdterminowanymi, które wygladaj¡ jak losowe (dla dobrych generatorów) wedªóg pewnej
liczby testów statystycznych. Aby przeksztaªci¢ je do liczb rzeczywistych z przedziaªu
3
Wedªug tego, co autor rozumiaª ogl¡dan¡c kod
89
[0; 1),
m (i otrzymuje si¦ generator liczb rzeczywistych, który w przybli»eniu speªnia rozkªad jednostajny na [0; 1)). Skªadnik pocz¡tkowy szeregu jest cz¦sto zwany
inicjatorem i przyjmuje domy±lnie warto±¢ X0 = 0. Zatem pierwsze wywoªanie rand(pierwszy
dzieli si¦ otrzyman¡ dan¡ przez
otrzymany wspóªczynnik je±li wypeªniamy macierz lub wektor) jest zawsze :
u1 = 453816693=231 0:2113249
Istnieje mo»liwo±¢ zmiany, w dowolnym momencie inicjatora za pomoc¡ instrukcji :
rand("seed",inicjator)
gdzie inicjator jest zawarty w przedziale
[0; m
1].
Cz¦sto istnieje potrzeba zainicjowania
szeregu poprzez wybór inicjatora mniej lub bardziej przypadkowo (sytuacja taka, aby nie mie¢
tej samej liczby za ka»dym razem), mo»emy chcie¢ na przykªad otrzyma¢ losowo dat¦ lub
godzin¦.
Scilab dysponuje funkcj¡
getdate
która generuje wektor zªo»ony z 9 elementów.
W±ród nich s¡:
drugi oznacza miesi¡c (1-12),
szósty, dzie« miesi¡ca (1-31),
siódmy, godzin¦ (0-23),
ósmy, minuty (0-59),
i dziewi¡ty, sekundy (0-61 ?).
Aby otrzyma¢ inicjator mo»na na przykªad dodawa¢ powy»sze elementy mi¦dzy sob¡ :
v = getdate()
rand("seed", sum(v([2 6 7 8 9])))
Zwró¢my uwag¦ równie» na mo»liwo±¢ zast¡pienia bierz¡cego inicjatora przez :
germe = rand("seed")
Pocz¡wszy od rozkªadu jednostajnego na
[0; 1), mo»na otrzyma¢ inne rozkªady a funkcja rand
dostarcza dostateczny interface pozwalaj¡cy otrzyma¢ rozkªad normalny (±rednia 0 i wariancja
1). Aby przej±¢ od jednego do drugiego, stosuje sie nast¦puj¡c¡ skªadnie :
rand("normal") // aby otrzymac rozklad normalny
rand("uniform") // aby powrocic do rozkladu jednostajnego
Domy±lnie generator przyjmuje rozkªad jednostajny ale jest rozs¡dnie w ka»dej symulacji upewni¢ sie czy
rand
daje oczekiwany wynik u»ywaj¡c jedn¡ w tych instrukcji. Mo»na zraszt¡
sprawdzi¢ aktualny rozk¡ad za pomoc¡ :
loi=rand("info") // jeden z rozkladow: "jednostajny" lub "normalny"
Ponowne wywoªanie
1.
A = rand(n,m)
2. je±li
B
rand
mo»e przyj¡¢ nast¦puj¡ce formy :
uzupeªnia macierz
A
(n,m) liczbami losowymi ;
jest macierz¡ ju» zdeniowan¡ o wymiarach
(n; m)
efekt (pozwala unikn¡¢ poszukiwania wymiarów macierzy
3. wreszcie,
u = rand()
to
B)
A = rand(B)
daje ten sam
;
daje pojedyncz¡ liczb¦ losow¡.
Do dwóch pierwszych metod mo»na doda¢ argument aby wskaza¢ dodatkowo rozkªad :
rand(n,m,loi), A = rand(B,loi),
uniform.
gdzie
loi
90
jest jednym z dwóch ªa«cuchów
normal
A =
lub
Wybrane zastosowania z u»yciem funkcji
rand
Pocz¡wszy od rozkªadu jednostajnego, w prosty sposób mo»na otrzyma¢ macierz (n,m) liczb
wdªug :
1. rozkªad jednostajny na
[a; b] :
X = a + (b-a)*rand(n,m)
2. rozkªad jednostajny na liczbach caªkowitych z przedziaªu
[n1 ; n2 ] :
X = floor(n1 + (n2+1-n1)*rand(n,m))
(losujemy nast¦puj¡ce liczby rzeczywiste rozkªadu jednostajnego na przedziele rzeczywistym
[n1 ; n2 + 1) a nast¦pnie bierzemy ich cz¦±¢ caªkowit¡).
Symulacja pojedynczej próby Bernulliego z prawdopodobie«stwem sukcesu
p:
succes = rand() < p
4 symuluj¡cej rozkªad dwumianowy
otrzymujemy dzi¦ki prostej metodzie
B (N; p) :
X = sum(bool2s(rand(1,N) < p))
(bool2s przekstaªca sukcesy w
1 i nie sumuje ich w funkcji sum).
Z uwagi na fakt, »e wykony-
wanie iteracji przez Scilaba jest do±c wolne, mo»na otrzyma¢ bezpo±rednio wektor (kolumnowy)
skªadaj¡cy si¦ z
m realizacji tego rozkªadu :
X = sum(bool2s(rand(m,N) < p),"c")
ale ko»ystne b¦dzie u»ycie funkcji
5
grand,
która u»ywa metod¦ bardziej ambitn¡.
Z drugiej
strony, je±li u»ywacie tego sposobu , jest bardziej przej»y±cie aby kodowa¢ go jako funkcj¦ Scilaba. A oto prosta funkcja symuluj¡ce rozkªad geometryczny (ilo±¢ prób Bernulliego potrzeb-
6 :
nych aby otrzyma¢ sukces)
function [X] = G(p)
// rozklad geometryczny
X = 1
while rand() > p // porazka
X = X+1
end
endfunction
Wreszcie, w nawi¡zaniu do rokªadu Normalnego
(±rednia
N (0; 1), otrzymamy rozkªad Normalny N (; 2)
i odchylenie standardowe ) za pomoc¡ :
rand("normal")
X = mu + sigma*rand(n,m) // aby otrzymac macierz (n,m) tych liczb
// lub przy uzyciu pojedynczej instrukcji : X = mu + sigma*rand(n,m,"normal")
5.2.2 Funkcja grand
W skomplikowanych symulacjach wyko»ystuj¡cych wiele liczb losowych klasyczna funkcja
z jej okresem rz¦du
u»ycie
grand
231 (' 2:147 109 ) mo»e okaza¢ si¦ troch¦ za ciasna.
która równie» umo»liwia symulacj¦ wszystkich klasycznych rozkªadów.
u»ywa sie prawie w taki sam sposób co
5
6
ale bardzo efektywnej dla du»ych
N !
w ogólno±ci u»ywa¢ b¦dziemy funkcji
grand
pozwala otrzyma¢ wiekszo±¢ klasycznych rozkªadów
ta funkcja jest bardziej efektywna dla maªych
grand
rand, tzn. »e mo»na u»y¢ jednej z dwóch nast¦puj¡cych
A musi by¢ zdeniowana w momencie jaj wywoªania) :
skªadni (oczywi±cie dla drugiej macierz
4
rand
Jest zatem wskazane
p.
91
grand(n,m,loi, [p1, p2, ...])
grand(A,loi, [p1, p2, ...])
où
loi
oznacza ªa«cuch znaków precyzuj¡cy rozkªad po którym nas¦puj¡ ewentualnie jego
parametry. Kilka przykªadów (aby otrzyma¢ prób¦
n realizacji, pod postaci¡ wektora kolum-
nowego) :
1. rozkªad jednostajny na liczbach caªkowitych z du»ego przedziaªu
[0; m[ :
X = grand(n,1,"lgi")
gdzie
m zale»y od generatora bazy (domy±lnie m = 232 ) ;
2. rozkªad jednostajny na liczbach caªkowitych z przedziaªu
[k1 ; k2 ] :
X = grand(n,1,"uin",k1,k2)
(musi by¢ speªniony warunek aby
k2 k1 2147483561 bo w przeciwnym wypadku prob-
lem ten jest sygnalizowany jako bª¡d);
3. dla rozkªadu jednostajnego na przedziale
[0; 1) :
X = grand(n,1,"def")
4. dla rozkªadu jednostajnego na przedziaªe
[a; b) :
X = grand(n,1,"unf",a,b)
5. dla rozkªadu dwumianowego
B (N; p) :
X = grand(n,1,"bin",N,p)
6. dla rozkªadu geometrycznego
G(p) :
X = grand(n,1,"geom",p)
:
7. dla rozkªadu Poissona ze ±redni¡
X = grand(n,1,"poi",mu)
8. dla rozkªadu wykªadniczego ze ±redni¡
:
X = grand(n,1,"exp",lambda)
9. dla rozkªadu normalnego ze ±redni¡
i odchyleniem standardowym :
X = grand(n,1,"nor",mu,sigma)
Inne przykªady mo»na znale¹¢ na stronach pomocy.
Pocz¡wszy od wersji 2.7
grand
jest wyposarzony w ró»ne generatory bazowe (ktore generuj¡
liczby wedªug rozkªadu lgi). Domy±lnie
czny okres rz¦du
219937
grand
u»ywa
MensenneT wister, który ma giganty7
oraz istnieje we wszystkoch 6 generatorach .
Aby operowa¢ tymi generatorami, mo»na u»y¢ nast¦puj¡cych instrukcji:
nom_gen = grand("getgen")
grand(±etgen",nom_gen)
etat = grand("getsd")
grand(±etsd",e1,e2,..)
7
zwraca (nazw¦) bierz¡cego generatora
generator
,
zwraca stan wewn¦trzny bierz¡cego generatora
"mt"
,
,
¢lcg4"
¢lcg2"
"fsultra"
i "urand"
, ten ostatni b¦d¡cy poprostu generatorem
staje si¦ bierz¡cym generatorem
ustawia wewn¦trzny stan bierz¡cego generatora
,"kiss"
,
nom_gen
rand.
92
Wymiar stanu wewn¦trznego ka»dego generatora zale»y od jego typu: od jednej wchodz¡cej
dla
urand
do 624 wchodz¡cych plus index dla
Mersenne Twister8 .
Je»eli chcecie wykona¢
ponownie t¦ sam¡ symulacj¦, musicie zna¢ stan wewn¦trzny (z przed symulacji) u»ywanego
generatora oraz go zapisac w taki lub inny sposób. Przykªad:
grand("setgen","kiss")
e = [1 2 3 4];
// kiss staje sie generatorem bierzacym
// stan jaki chce palowyc na kiss
// (musi miec 4 wejsciowe)
grand("setsd",e(1),e(2),e(3),e(4));
// zrobione!
grand("getsd")
// musi zwrocic wektor e
X = grand(10,1,"def");
// 10 liczb
s1 = sum(X);
X = grand(10,1,"def");
// znowu 10 liczb
s2 = sum(X);
s1 == s2
// ogolnie s1 bedzie sie roznic od s2
grand("setsd",e(1),e(2),e(3),e(4));
// powrot do stanu pierwotnego
X = grand(10,1,"def");
// znowu 10 liczb
s3 = sum(X);
s1 == s3
// s1 musi byc rowne s3
5.3
Dystrubuanty i ich odwrotno±ci
2r , ...)
Dystrybuanty s¡ cz¦sto u»ywane przy testach statystycznych (
poniewa» pozwalaj¡ na
obliczenia, niech :
1. dystrybuanta w 1 lub kilku punktach ;
2. jej odwrotno±¢ w 1 lub kilku punktach ;
3. jeden z parametrów rozkªadu jest dany przez pozostaªe i par¦
(x; F (x)) ;
W Helpie, dystrybuanty mo»na znaleŸ¢ pod hasªem Cumulative Distribution Functions...,
wszystkie te funkcje poprzedzone s¡ skrótem
cdf.
Przykªadowo dla rozkªadu Normalnego
N (; 2), funkcja która nas interesuje nosi nazw¦ cdfnor i jej skªadnia jest nast¦puj¡ca :
1.
2.
3.
[P,Q]=cdfnor("PQ",X,mu,sigma) aby otrzyma¢ P = F; (X ) i Q = 1 P , X, mu oraz
sigma mog¡ by¢ wektorami (o tych zamych wymiarach) i wówczas otrzymuje sie dla P i Q
wektor za pomoc¡ Pi = Fi ;i (Xi ) ;
[X]=cdfnor("X",mu,sigma,P,Q) aby otrzyma¢ X = F;1 (P ) (podobnie jak poprzednio
argumentami mog¡ by¢ wektory o tych zamych wymiarach i wówczas otrzymuje si¦ Xi =
Fi1;i (Pi ) ;
[mu]=cdfnor("Mean",sigma,P,Q,X) aby otrzyma¢ ±redni¡ ;
4. i ostatecznie
[sigma]=cdfnor("Std",P,Q,X,mu)
aby dosta¢ odchylenie standardowe.
Dwie ostatnie skªadnie funkcjonuj¡ tak»e gdy argumentami s¡ wektory o jednakowych wymiarach.
Uwagi :
p oraz q = 1 p pozwala uzyska¢ precyzj¦ w obszarze gdzie
p jest bliskie 0 lub 1. Dla p bliskiego 0 funkcja wyko»ystuje warto±¢ p, natomiast dla p
bliskiego 1 funkcja wyko»ystuje warto±¢ q ;
mo»liwo±¢ jednoczesnej pracy z
ªa«cuch znaków pozwalaj¡cy otrzyma¢ funkcj¦ odwrotn¡ nie zawsze ma posta¢
zobacznie na odpowiednich stronach pomocy.
8
procedura inicjuj¡ca wraz z pojedy«czym wej±ciem istnieje nie mniej jednak dla tego generatora.
93
"X"...
5.4
Proste symulacje stochastyczne
5.4.1 Wprowadzenie i notacja
Cz¦sto symulacja polega przede wszystkim na otrzymaniu wektora :
xm = (x1 ; ::::; xm )
którego skªadowe s¡ rozumiane jako realizacje niezale»nych zmiennych losowych i podobnie
rozkªad
X1 ; X2 ; ::::; Xm
rand
lub
grand9 .
W przypadku próby
X zmienn¡ losow¡ generuj¡c¡ ten sam
xm otrzymuje sie bezpo±rednio lub po±rednio za pomoc¡ funkcji
(b¦dziemy oznacza¢ przez
rozkªad). W praktyce wektor
xm poszukujemy zbli»onych charakterystyk jej rozkªadu takich jak warto±¢
oczekiwana, odchylenie standardowe, dystrybuanta (lub funkcja g¦sto±ci) lub te» gdy stawiamy
hipotez¦ dotycz¡c¡ rozkªadu, aby okre±li¢ jej parametry, albo, gdy parametry s¡ ju» znane,
werykowa¢ za pomoc¡ testów statystycznych, »e nasza próba jest (mo»liwie) dobrze reprezentatywn¡ zmienn¡ losow¡ która pod¡»a efektywnie za rozkªadem itd... <-???????????????????????????
Dla przypadków, które nas interesuj¡, znane s¡ przewa»nie dokªadne wyniki teoretyczne, a
symulacja sªu»y jedynie do zilustrowania wniosków, twierdze« (lgn?, TCL =? CTG, itd...),
dziaªania metody lub algorytmu, ...
5.4.2 Przedziaªy ufno±ci
Niekiedy o empirycznej warto±ci oczekiwanej otrzymanej z naszej próby (w Scilabie :
= mean(xm)) chcieliby±my powiedzie¢, »e mie±ci si¦ w pewnym przedziale.
x_bar_m
Ponadto chcieliby±my
zna¢ ów przedziaª aby móc zapisa¢, »¦ :
E [X ] 2 Ic
= 0:05
gdzie najcz¦±ciej
lub
0:01
z prawdopodobie«stwem
1
(przedziaªy ufno±ci odpowiednio 95% i 99%).
W celu
wyznaczenia tych przedziaªów za punkt wyj±cia posªu»y na C.T.G.. Je±li przyjmiemy :
m
1X
X m =
X
m i=1 i
xm jest pojedyncz¡ realizacj¡), wówczas prowo
zbie»ne do E [X ] i na mocy C.T.G (przy pewnych
za zmienn¡ losow¡ dla warto±ci ±redniej (gdzie
wielkich liczb mówi nam, »e
zaªo»eniach...) mamy :
X m
jest
pm(X
Z
b
1
2
p
lim
P
(
a
<
b
)
=
e t =2 dt
m !+ 1
2 a
2
(przyjmuje si¦, »e V ar [X ] = ). Dla dostatecznie du»ych m przyjmuje si¦, »e :
pm(X E [X ])
Zb 2
1
m
P (a <
b) p
e t =2 dt
2 a
m
E [X ])
Je»eli chcemy aby przedziaª ufno±ci byª symetryczny :
p1
2
9
Z
a
a
e
t2 =2 dt = F
N (0;1) (a)
FN (0;1) ( a) = 2FN (0;1) (a) 1 = 1
w wi¦kszo±ci przypadków próba statystyczna dotyczy miar zycznych (temperatura, ci±nienie,...), biometrycznych
(wzrost,waga), sonda»y, itd... otrzymane dane s¡ zbierane w plikach (lub bazach danych); pewne programy (jak R) proponuj¡ dla nich ukªad danych (dla których studenci b¦d¡ mogli robi¢ r¦cznie !) niestety Scilab nie dysponuje tak¡ mo»liwo±ci¡; niemniej przypadków gdzie u»ywamy takich symulacji jest równie wiele, na przykªad aby przestudiowa¢ zachowanie
pewnych systemów wej±ciowych (lub zakªuce«) losowych lub podobnie aby rozwi¡za¢ problemy czysto deterministyczne ale
dla których metody analizy numerycznej s¡ zbyt skomplikowane lub niemo»liwe do zaimplementowania<-??? .
94
wówczas :
1 (1
a = FN (0
;1)
2
1 ( )
FN (0
;1) 2
) albo
co zapisuje si¦ w scilabie :
a_alpha = cdfnor("X", 0, 1, 1-alpha/2, alpha/2)
Otrzymujemy ostatecznie
10 :
a a p
; xm + p ]
m
m
E [X ] 2 [xm
1
z prawdopodobie«stwem
(je»eli przybli»enie granicy jest poprawne...).
Problem pojawia si¦ w momencie gdy nieznane jest odchylenie standardowe... Wyko»ystuje
v
u
m
u 1 X
Sm = t
(Xi X m )2
m 1
si¦ wówczas etymator :
i=1
Zast¦puj¡c odchylenie standardowe
przez sm (gdzie sm jest pojedyncz¡ realizacj¡ Sm ), otrzy-
mujemy przedziaª ufno±ci, który przyjmujemy równie» dla warto±ci empirycznej.
Szczególne przypadki :
1. je±li
Xi ma rozkªad normalny N (; 2 ) wówczas :
pm Xm t(m 1)
Sm
gdzie
t(k)
ma rozkªad Studenta o
k
stopniach swobody.
w tym przypadku wszelkie
poprzednie przybli»enia trac¡ moc (przybli»enie granicy i przybli»enie odchylenia standardowego) oraz otrzymuje sie :
2 [xm
gdzie
sm
a sm
pm ; xm + apsmm ]
avec probabilité
1
jest empirycznym odchyleniem stndardowym z próby (sm
w scilabie) gdzie
a
= st_deviation(xm)
jest warto±ci¡ krytyczn¡ rozkªadu Studenta :
a = Ft(m1 1) (1
2
)
11 przez :
otrzyman¡ w scilacie
a_alpha = cdft("T", m-1, 1-alpha/2, alpha/2)
2. w momencie gdy wariancja wyra»a si¦ przez funkj¦ warto±ci oczekiwanej (Bernouilli, Poisson, wykªadniczy,...) mo»na pzsªu»y¢ die przybli»eniem odchylenia standardowego i otrzymuje si¦ przedziaª ufno±ci poprzez rozwi¡zanie odpowiedniej nierówno±ci.
5.4.3 Wykres dystrubuanty empirycznej
Dystrybuant¡ zmienne losowej
X
nazywamy funkcj¦ :
F (x) = Probabilité que X x
10
11
dla przedziaªu z 95%, mamy
a
' 1:96 cz¦sto zast¦powane przez 2.
zobacz na odpowiednich stronach pomocy : wªa±ciwie funkcje
cdf
nie maj¡ regularnej/uniwersalnej skªadni i
musi by¢ zawsze oznaczeniem pozwalaj¡cym otrzyma¢ funkcj¦ odwrotn¡ do dystybuanty, tutaj jest to
95
"T"
!
"X"
nie
Dystrybuanta empiryczna pochodz¡ca z próby
xm jest deniowana jako :
Fxm (x) = cardfxi <= xg=m
Jest to funkcja schodkowa, któr¡ liczy si¦ ªatwo je±li posortujemy wektor
cym (mamy wi¦c
Fxm (x) = i=m dla xi x < xi+1 ).
w scilabie jest funkcja
sort która sortuje malej¡co12 .
xm w porz¡dku rosn¡-
Standardowym algorytmem sortuj¡cym
Aby posortowa¢ wektor
xm w porz¡dku
rosn¡cym u»yjemy :
xm = - sort(-xm)
£atwym sposobem narysowania wykresu jest funkcja
plot2d2.
Oto przykªadowy kod :
dystrybuanta_empiryczna(xm)
// wykres dystrybuanty (empirycznej)
// na próbie xm
m = length(xm)
xm = - sort(-xm(:))
ym = (1:m)'/m
plot2d2(xm, ym, leg="dystrybuanta empiryczna")
endfunction
Zwró¢my uwag¦ na zapis :
xm(:), który jest analogiczny do zapisywania wektora wierszowego.
A teraz przykªad dla rozkªadu normalnego
N (0; 1) :
m = 100;
xm = grand(m,1,"nor",0,1);
xbasc()
dystrybuanta_empiryczna(xm); // wykres fct dystrybuanty empirycznej
// dane dla wykresu dystrybuanty "dokladnej"
x = linspace(-4,4,100)';
y = cdfnor("PQ", x, zeros(x), ones(x));
plot2d(x, y, style=2)
// nanosimy krzywa na pierwszy wykres
xtitle("Dystrybyanty dokladna i empiryczna")
który daje nast¦puj¡cy wykres (5.3).
Rysunek 5.3: Systrybuanta dokªadna i empiryczna rozkªadu normalnego
5.4.4 Test 2
xm = (x1 ; :::; xm ) b¦dzie nasz¡ prób¡ dla dalszej analizy. Niech b¦dzie dana hipoteza H
zmienne losowe postaci (X1 ; :::; Xm ) maj¡ rozkªad L. Chcemy wiedzie¢ czy hipoteza jest
Niech
:
prawdziwa czy nie.
Dla naszej próby mo»na bez w¡tpienia obliczy¢ statystyki elementarne
(±redni¡ i odchylenie standardowe empiryczne) i je»eli s¡ one dostatecznie bliskie warto±ci
oczekiwanej oraz odchyleniu standardowemu rozkªadu
statystyczny.
Test
2
Na przykªad zakªadaj¡c, »e rozkªad
y=
zobacz tak»e funkcj¦
gsort,
mo»na wówczas zastosowa¢ test
L jest zadany przez f(vi; pi); 1 i ng.
obliczeniu wielko±ci :
12
L,
stosuje si¦ dla rozkªadów dyskretnych o sko«czonej liczbie warto±ci.
Pn
i=1 (oi
mpi
która robi wi¦cej rzeczy
96
mpi )2
Test polega na
gdzie
oi
jest liczb¡ realizacji
xj
równych
vi
i na przyrównaniu otrzymanej wielko±ci
y
do
yy .
Je»eli do rówanania na y wstawiwy w miejsce próby x1 ; :::; xm , zmienne losowe X1 ; :::; Xm w
14 zmienn¡ losow¡ Y , któr¡ mo»na przybli»a¢ (dla dostatecznie du»ych
ten sposób zdeniujemy
2
m) rozkªadem o n 1 stopniach swobody. Warto±¢ progow¡ otrzymujemy przez :
y = F 21 (1 )
warto±ci progowej
y
13 je±li
, test b¦dzie pozytywny
n 1
przy
= 0:05 lub
= 0:01.
W Scilabie warto±¢ t¦ otrzymamy poprzez :
y_progowe = cdfchi("X", n-1, 1-alpha, alpha)
Aby obliczy¢ cz¦sto±¢
oi za pomoc¡ Scilaba mo»emy u»y¢ nast¦puj¡cej metody :
occ = zeros(n,1);
for i=1:n
occ(i) = sum(bool2s(xm == v(i))); // albo length(find(xm==v(i)))
end
if sum(occ) ~= m then, error("b\l{}\k{a}d oblicze\'n"), end
I aby otrzyma¢ wielko±¢
y mo»na napisa¢ (stosuj¡c zapis wktorowy15 ) :
y = sum( (occ - m*p).^2 ./ (m*p) )
pod warunkiem, »e
co
occ
p (wektor przwdopodobie«stw rozkªadu L), b¦dzie tych samych wymiarów
(tutaj wektor kolumnowy ??????????).
Uwagi :
2 jest wa»ne gdy m
= mini pi ) jako minimalny
przybli»anie rozkªadem
mpmin > 5 (pmin
jest dostatecznie du»e...
»adamy cz¦sto
warunek zastosowania tego testu; w ten
sposób mo»ecie werykowa¢ to zaªo»enie i napisa¢ wiadomo±¢ aby uprzedzi¢ u»ytkownika
je»eli nie jest speªnione.
mo»na ªatwo pogrupowa¢ te obliczenia w funkcji;
dla rozkªadu ci¡gªego test mo»e si¦ stosowa¢ grupuj¡c wielko±ci na przedziaªy, na przykªad
dla rozkªadu
U[0;1] ,
stosuje si¦
n
równomiernie rozªo»onych przedziaªów; podobnie dla
rozkªadu dyskretnego o niesko«czonej liczbie wielko±ci, mo»na pogrupowa¢ je w kolejki
rozkªadu; podobn¡ procedur¦ mo»na zastosowa¢ dla roskªadów sko«czonych dla których
warynek zastosowania testu nie jest speªniony.
je»eli testujecie rozkªad w którym pewne parametry zostaªy wcze±niej obliczone na podstawie danych, nale»y okre±li¢ liczb¦ stopni swobody dla rozkªadu
spodziewamy si¦ rozkªadu
2
; na przykªad je±li
B (n 1; p) i u»yjemy p = xm =(n 1) wówczas nieprzekraczaln¡ warto±y = F21 (1
) a nie y =
n 2
ci¡ progow¡ dla testowanej hipotezy zerowej b¦dzie
F21 (1
n 1
).
5.4.5 Test Koªmogorowa-Smirnova
X b¦dzie rzeczywist¡ zmienn¡ losow¡ dla której dystrybuanta rozkªadu jest funkcj¡
F oraz X1 , X2 ,..., Xm , m niezale»nych zmiennych losowych. Dla realizacji Xi (mówimy
m = (x ; ::::; x )), mo»na skonstruowa¢ dystrybuant¦ empiryczn¡ która przy (m !
wektor x
1
m
+1) d¡zy do dystrybuanty teoretycznej. Test KS polega na okre±leniu ró»nicy pomi¦dzy
Niech
ci¡gª¡
13
14
15
oi nie odbiega zbytnio od mpi , zatem je»eli
y , sk¡d odrzucimy hipotez¦ dla y > y ...
z intuicyjnego punktu widzenia je»eli hipoteza jest dobra oczekujemy, »e
hipoteza jest faªszywa oczekujemy »e otrzymamy wysok¡ warto±¢
poprzez zmienn¡ losow¡ wektorow¡
O = (O1 ; :::; On ) maj¡c¡ rozkªad wielomianowy<-?????
¢wiczenie: przeksztaª¢ t¦ instrukcj¦ wektorow¡ aby zrozumie¢ jak (i dlaczego) dziaªa.
97
dystrybuant¡ teoretyczn¡ i empiryczn¡ (otrzyman¡ na podstawie naszej próby
p
w nast¦puj¡cy sposób :
km = m
sup jF (x)
1<x<+1
(x1 ; ::::; xm ))
Fxm (x)j
i na porównaniu jej z wielko±ci¡ dopuszczaln¡. Je»eli zast¡pimy nasz¡ realizac¦ przez odpowied-
km staje si¦ równie» zmienn¡ losow¡ (któr¡ zapisujemy jako Km ).
nie zmienne losowe, wówczas
Zgodnie z teori¡ jej dystrybuanta jej rozkªadu jest nast¦puj¡ca :
lim P (Km x) = H (x) = 1 2
m!+1
i odrzycimy t¦ hipoteze gdy:
= 0:05
lub
0:01
km > H 1 (1
na przykªad.
)
Je±li u»ywamy przybli»enia
nieprzekraczalna warto±¢ progowa jest :
kseuil =
Obliczenie
j =1
2 2
( 1)j 1 e 2j x
2 , je»eli rozwa»ana hipoteza jest faªszywa, otrzymane warto±ci km b¦d¡ du»e
Jak przy te±cie
z
+1
X
r
H (x)
' 1 2e 2x2
wówczas
1 2
ln( )
2
km nie sprawia problemu je»eli posortuje si¦ wektor (x1 ; x2 ; : : : ; xm ).
Sortowaniw
b¦dzie efektywne gdy zwrócimy uwag¦ ne fakt aby :
sup
x2[xi ;xi+1 [
i
m
Fxm (x) F (x) =
F (xi );
sup
et
x2[xi ;xi+1 [
F (x) Fxm (x) = F (xi+1 )
i
m
dwie nast¦pne wielko±ci mo»na ªatwo policzy¢ :
p
+= m
km
p
km = m
p
j
(Fxm (x) F (x)) = m max (
1
j
m
m
1<x<+1
sup
F (xj ))
p
j 1
)
m
(F (x) Fxm (x)) = m max (F (xj )
1 j m
1<x<+1
+
i otrzymujemy w ten sposób km = max(km ; km ).
sup
5.4.6 ¢wiczenia
Czy to sprawka kostki ?
Rzucamy 200 razy symetryczn¡ kost¡ do gry, do±wiadczenie jest nast¦puj¡ce : rzucamy tyle
razy a» wypadnie 1 (ale nie wi¦cej ni» 10 rzutów). Otrzymali±my nast¦puj¡ce wyniki :
liczba rzutów
1
2
3
4
5
6
7
8
9
10
11
ilo±¢ do±wiadcze«
36
25
26
27
12
12
8
7
8
9
30
na przykªad 36 razy jedynka pojawiªa sie w pierwszym rzycie, 25 razy jedynka pojawiªa sie w
drugim »ucie, itd...
Wykona¢ test
2 aby udzieli¢ odpowiedzi na postawione pytanie.
98
Urna Polya
Losujemy
N
razy z urny
Polya
zawieraj¡cej pocz¡tkowo
r
kul czerwonych i
v
kul zielonych.
Ka»de losowanie polega na wyci¡gni¦ciu jednej kuli i jej odªo»eniu spowrotem do urny wraz z
c kulami tego samego koloru. Przez Xk oznaczamy stosunek kul zielonych po k losowaniach
do sumy kul, Vk oznacza ilo±¢ kul zielonych :
v
X0 =
; V = v:
v+r 0
Je»eli v = r = c = 1, wynik b¦dzie nast¦puj¡cy :
1. E (XN ) = E (X0 ) = X0 = 1=2 ;
1
N +1
2. XN ma rozkªad normalny na zbiorze f
N +2 ; :::::; N +2 g ;
3. dla N ! +1, XN jest zbie»ne do rozkªadu jednostajnego na przedziale [0; 1).
Wyko»ystacie symulacj¦ aby zilustrowa¢ dwa pierwsze wyniki.
1. Aby przeprowadzi¢ ró»ne symulacje, mo»na napisa¢ funkcj¦ zale»n¡ od parametru
która wykonuje
N
kolejnych losowa«. Funkcja ta zwraca wi¦c
XN i VN
N
i
:
function [XN, VN] = Urna_Polya(N)
// symulacja N losowan z "Urny Polya" :
VN = 1 ; V_plus_R = 2 ; XN = 0.5
for i=1:N
u = rand() // losowanie jednej kuli
V_plus_R = V_plus_R + 1
// zwieksza ilosc kul
if (u <= XN) then // wylosowalislmy kule zielona : mamy XN prawdopodobienstw
// wylosowania kuli zielonej (1 - XN dla kuli czerwonej)
VN = VN + 1
end
XN = VN / V_plus_R // aktualizujemy stosunek kul zielonych
end
endfunction
niestety skuteczne wykonanie statystyk wymaga wielokrotnego wywoªania tej funkcji, a
zatem, z uwagi na stosunkowo powolne wykonywanie iteracji przez Scilab, nale»y naposa¢ funkcj¦ wykonuj¡c¡
m
procesów równolegªych .
Mo»na u»y¢ funkcji
find
aby
naprawi¢????? urny z których losujemy kule zielone.
2. Napisa¢ skrypt znajduj¡cy poprzez symulac¦ warto±¢ oczekiwan¡ (wraz z jej przedzieªem
ufno±ci).
3. Rozwin¡¢ poprzedni skrypt testuj¡c hipotez¦
H
dotycz¡c¡ rozkªadu zmiennej losowej
1
N +1
H : XN ma rozkªad jednostajny na zbiorze f
N +2 ; :::::; N +2 g
2
za pomoc¡ testu .
XN
4. Porówna¢ wyniki gracznie, na przykªad rysuj¡c na jednym rysunku dystrybuant¦ empiryczn¡ i teoretyczn¡, lub te» narysowa¢ wykres funkcji g¦sto±ci rozkªadu
2
dla otrzy-
manych wielko±ci przez ten test, wielko±ci progowe zaznaczy¢ liniami pionowymi.
Most ?????
Proces stochastyczny (w którym
U
oznacza rozkªad jednostajny na przedziale
n
1 X
Xn (t) = p
(1
n i=1 fUi tg
jest taki, »e dla ustalonego
t)
t 2]0; 1[ mamy :
lim X (t) = Y (t) N (0; t(1
n !+ 1 n
99
t))
[0; 1]) :
Chcemy zilustrowa¢ wyniki za pomoc¡ symulacji.
Schemat pracy :
1. Napisa¢ funkcj¦ Scilaba
alizacj¦
function [X] = pont_brownien(t,n) pozwalaj¡c¡ otrzyma¢ re-
Xn (t) ; w ci¡gu wywoªamy t¦ funkcj¦ m razy z warto±ci¡ n dostatecznie du»ym16
nale»y zatem napisa¢ j¡ bez u»ycia pentli.
2. Napisa¢ sktypt scilaba wyko»ystuj¡c t¦ symulacj¦ mostu Brownien : wykona¢
m symulacji
Xn (t) (z du»ym n) i przedstawi¢ gracznie zachowanie rozkªadu (rysuj¡c jego dystrybuant¦
empiryczn¡ i nakªadaj¡c na ni¡ dystrybuant¦ teoretyczn¡ Y (t)) a nast¦pnie zastosowa¢
test Koªmogorowa-Smirnova.
Mo»na umie±ci¢ poprzedni¡ funkcj¦ na pocz¡tku skryptu
aby pracowa¢ tylko z jednym plikiem.
m i n : kiedy m wierzy ...?????????????.......gdz
n nie jest dostatecznie du»e (poniewa» rozkªad normalny otrzymuje si¦ z granicy gdy n ! +1), nale»y zatem zwi¦kszy¢ n... Dla t = 0:3, mo»ecie
na przykªad przetestowa¢ z n = 1000 i m = 200; 500; 1000, i test daje dobre wyniki (»adko
od»uca hipotez¦ zerow¡) ale dla m = 10000 test jest prawie zawsze negatywny. Je»eli zwi¦kszymy n (na przykªad do n = 10000 ale obliczenia zaczynaj¡ by¢ nieco dªu»sze na komputerze
Uwaga :
nie jest ªatwo dobra¢ odpowiednie wielko±ci dla
test si¦ nie powiódª poniewa» uznaª, »e
PC wykonanym w 2003) wówczas test ponownie staje si¦ normalnie pozytywny.
16
aby przybli»y¢
Y ( t) !
100
Rozdziaª 6
Ciekawostki
W tej cz¦±ci przedstawiono/przytoczono przegl¡d niektórych bª¦dów cz¦sto spotykanych w
Scilabie...
6.1
Deniowanie wektora i macierzy wspóªczynnik po wspóªczyn-
niku
Ten bª¡d jest jednym z najcz¦strzych. Rozwa»my nast¦puj¡cy skrypt :
K = 100 // jedyny parametr w tym skrypcie
for k=1:K
x(k) = cos
y(k) = cos innego
end
plot(x,y)
Je»eli uruchomimy ten skrypt po raz pierwszy, zostan¡ zdeniowane dwa wektory
x i y.
Po-
jawia si¦ jeden maªy bª¡d poniewa» w ka»dej iteracji Scilab redeniuje rozmiary tych wektorów
(nie wie, »e ich wymiarem ko«cowym b¦dzie (K,1)). Zauwa»my równie», »e domy±lnie stworzy
wektor kolumnowy. Podczas drugiero wywoªania (zmieniaj¡c parametr
znane i takie, »e
k
s¡ rówenie» ich wspóªrz¦dne. W konsekwencji je»eli nowa warto±¢
K < 100
jest tylko
K > 100
wówczas nasze wektory
K
K...)
wektory
xiy
s¡
jest mniejsze od 100 (pocz¡tkowa wielko±¢ parametru K) zatem zmieniane
x
i
y
K
jest taka, »e :
maj¡ zawsze 100 wspóªrz¦dnych (zmodykowane
pierwszych) a wykres nie pokazuje tego co oczekujemy ;
nie pojawia si¦ »aden problem (za wyj¡tkiem tego, »e rozmiar wektora jest za
ka»dym razem aktualizowany pocz¡wszy od 101 iteracji)
Najlepszym sposobem jest zdeniowanie wektorów
xiy
za pomoc¡ inicjalizacji ich rodzaju :
x = zeros(K,1) ; y = zeros(K,1)
w ten sposób uniknie si¦ wszelkich bª¦dów. Nasz skrypt zatem przyjmie posta¢ :
K = 100 // jedyny parametr w tym skrypcie
x = zeros(K,1); y = zeros(K,1);
for k=1:K
x(k) = cos
y(k) = cos innego
end
plot(x,y)
101
6.2
Na temat warto±ci zwracanych przez funkcj¦
Zaªó»my, »e mamy zaimplementowan¡ funkcj¦ w Scilabie zwracaj¡c¡ dwa argumenty, na
przykªad :
function [x1,x2] = resol(a,b,c)
// rozwi\k{a}zanie równania kwadratowego a x^2 + b x + c = 0
// formu\l{}ad poprawiona dla wi\k{e}kszo\'sci metod numerycznych
// (w celu unikni\k{e}cia odejmowania dwóch s\k{a}siednich liczb)
if (a == 0) then
error(" nie rozwa\.zamy przypadku gdy a=0 !")
else
delta = b^2 - 4*a*c
if (delta < 0) then
error(" nie rozwa\.zamy przypadku gdy delta < 0 ")
else
if (b < 0) then
x1 = (-b + sqrt(delta))/(2*a) ; x2 = c/(a*x1)
else
x2 = (-b - sqrt(delta))/(2*a) ; x1 = c/(a*x2)
end
end
end
endfunction
W ogólnym przypadku je»eli wywoªamy funkcj¦ w Scilabie w nast¦puj¡cy sposób :
-->resol(1.e-08, 0.8, 1.e-08)
ans =
- 1.250D-08
jej wynik jest przypisany zmiennej
ans.
Ale zmienna ta jest pojedyncz¡ liczb¡, a funkcja
zwraca dwie warto±ci z których tylko pierwsza jast przypisana zmienne
ans.
Aby zobaczy¢
drug¡ warto±¢ u»yjemy skªadni :
-->[x1,x2] = resol(1.e-08, 0.8, 1.e-08)
x2 =
- 80000000.
x1 =
- 1.250D-08
Inna, niebezpieczniejsza puªapka jest nast¦puj¡ca. Zaªó»my, »e znamy precyzj¦ z jak¡ dziaªa
aic
k) obliczymy wszystkie pierwiastki dla
ta formuªa (w stosunku do precyzji dziaªania formóª klasycznych). Aby dobra¢ warto±ci
(na przykªad
a = c = 10
k
przyjmuj¡c ró»ne warot±ci
kolejnych parametrów równania i ustawimy je jako dwa wektory sªu»ce do póŸniejszej analizy.
Najprostrzy schemat jest nast¦puj¡cy :
b = 0.8;
kmax = 20;
k = 1:kmax;
x1 = zeros(kmax,1); x2=zeros(kmax,1);
for i = 1:kmax
a = 10^(-k(i)); // c = a
[x1(i), x2(i)] = resol(a, b, a); // BLAD !
end
Taka skªadnia nie zadziaªa (jedynie w przypadku gdy funkcja zwraca jedn¡ warto±¢). Nale»y
wykona¢ to w dwóch krokach :
102
[rac1, rac2] = resol(a, b, a);
x1(i) = rac1; x2(i) = rac2;
Uwaga :
6.3
Problem ten jest rozwi¡zany w wercjach rozwijaj¡cych (cvs) dla Scilaba.
Funkcja zostaªa zmidykowana ale...
wszystko dziaªa tak jak przed modykacj¡ ! By¢ mo»e zapomnieli±cie zapisa¢ zmiany w waszym
edytorze albo, co jest bardziej prawdopodobne, zapomnieli±cie zaªadowa¢ plik zawieraj¡cy
funkcj¦ w Scilabie za pomoc¡ instrukcji
getf
(lub
exec)
pomoc¡ strzaªki
6.4
getf (lub exec) !
Jedna maªa wskazówka : instrukcja
jest z pewno¡ci¡ zapisana niedaleko w historii komend, wystarczy zatem za
" odszuka¢ t¦ instrukcj¦.
Problem z
Domy±lnie funkcja
rand
rand
dostarcza liczby losowe wedªug rozkªadu jednostajnego na przedziale
[0; 1[, mo»na jednak otrzyma¢ rozkªad normalny N (0; 1) za pomoc¡ : rand(«ormal").
Chc¡c
rand("uniform"). Aby unikn¡¢
funkcji rand. precyzowaªo rozkªad
powróci¢ do rozkªadu jednostajnego nale»y wpisa¢ instrukcj¦
tego problemu najlepiej pami¦ta¢ aby ka»de wywoªanie
który nas aktualnie interesuje (patrz poprzedni rozdziaª).
6.5
Wektory wierszowe, wektory kolumnowe...
W kontek±cie macierzowym ich posta¢ jest sprecyzowana, ale dla innych zastosowa« nie zawsze
s¡ one rozrózniane i stosuje sie funkcj¦ która dziaªa w obydwu przypadkach. Aby przyspieszy¢
obliczenia dobrze jest odwoªa¢ si¦ do skªakni macierzowej i wybra¢ jedn¡ lub drug¡ form¦
wektora. Mo»na wyko»ysta¢ funkcj¦
matrix
w nast¦puj¡cy sposób :
x = matrix(x,1,length(x)) // aby otrzyma\'c wektor wierszowy
x = matrix(x,length(x),1) // aby otrzyma\'c wektor kolumnowy
Chc¡c otrzyma¢ w prosty sposób wektor kolumnowy mo»na wyko±ysta¢ instrukcj¦ :
x = x(:)
6.6
Operator porównania
W pewnyc przypadkach Scilab akceptuje symbol
=
jako operator porównania :
-->2 = 1
Warning: obsolete use of = instead of ==
!
ans =
F
ale lepiej jest zawsze u»ywa¢ symbolu
6.7
==.
Liczby zespolone a liczby rzeczywiste
Scilab jest tak skonstruowany aby traktowa¢ liczby rzeczywiste w taki sam sposób jak liczby
zespolone !
px i log(x)
Jest to calkiem praktyczne ale mo»e niekiedy by¢ przyczyn¡ niespodzianek, na
przykªad podczas szacowania funkcji rzeczywistej poza jej dziedzin¡ (na przykªad
103
dla
x < 0,
acos
(x)
i asin
(x)
dla
x 2= [ 1; 1],
acosh
(x)
x < 1)
dla
) poniewa» Scilab zwraca
wówczas oszacowanie cz¦±ci zespolonej tej funkcji. Aby dowiedzie¢ si¦ czy dziaªamy na zmiennej zespolonej czy rzeczywistej nale»y u»y¢ funkcji
isreal
:
-->x = 1
x =
1.
-->isreal(x)
ans =
T
-->c = 1 + %i
c =
1. + i
-->isreal(c)
ans =
F
-->c = 1 + 0*%i
c =
1.
-->isreal(c)
ans =
F
6.8
Proste instrukcje a funkcje Scilaba
W niniejszym opracowaniu cz¦stu stosuje sie zamiennie terminów
prosta instrukcja i funkcja
aby wskaza¢ procedury dost¦pne w bie»¡cej werksji Scilaba. Istnieje jednak fundamentalna
ró»nica pomi¦dzy prost¡ instrukcj¡ która jest kodowana w fortranie 77 lub w C a funkcj¡
(zwan¡ równie» makro) która jest kodowana w j¦zyku Scilaba : funkcja jest wówcz¡s rozumiana jako zmienna Scilaba, i dzi¦ki temu mo»na j¡ u»y¢ jako argumentu dla inne funkcji.
Pocz¡wszy od wersji 2.7, proste instrukcje bywaj¡ zmiennymi w Scilabie (fptr).
Niemniej
jednak przysparzaj¡ wiele problemów (aktualnie rozwi¡zanych w rozwini¦ciach).
Oto przykªad problemu jaki mo»na spotka¢ : funkcja nast¦puj¡ca pozwalaj¡ca przybli»a¢ zbiór
przy zastosowaniu metody
Monte Carlo :
function [im,sm]=MonteCarlo(a,b,f,m)
//
/b
// przybli\.zenie | f(x) dx przy zastosowaniu metody Monte Carlo
//
/a
// zwracane jest równie\.z empiryczne odchylenie standardowe
xm = grand(m,1,"unf",a,b)
ym = f(xm)
im = (b-a)*mean(ym)
sm = (b-a)*st_deviation(ym)
endfunction
Jako argument
f
oczekuje si¦ funkcji Scilaba ale ten kod powienien równie» dziaªa¢ dla funkcji
1 poniewa» s¡ one teraz rozwa»ane
matematycznych które nale»¡ do prostych instrukcji Scilaba
1
na przykªad
sin, exp
i wiele innych.
104
jako zmienne. Niemniej jednak test z u»yciem prostej instrukcji
exp
nie powiedzie si¦ :
-->[I,sigma]=MonteCarlo(0,1,exp,10000) // bug !
Wywoªuj¡c funkcj¦
MonteCarlo
za pomoc¡
getf
z opcj¡ nie kompilowania :
-->getf("MonteCarlo.sci","n")
bª¡d ten [bug] (skorygowany w aktualnym cvs) b¦dzie wówczas omini¦ty.
6.9
Obliczanie wyra»e« logicznych
W przeciwie«stwie do j¦zyka C, obliczenie warto±ci logicznej wyra»e« :
a lub b
aib
poprzedzone jest wyliczeniem warto±ci logicznej
a i b,
dopiero potem zostanie wykonana na
nich operacja sumy czy iloczynu logicznego (Priorytety operatorów zamieszczono w rozdziale
Programowanie).
105
Dodatek A
Odpowiedzi do ¢wicze« z rozdziaªu 2
1.
--> n = 5 // dla ustalenia warto\'sci n...
--> A = 2*eye(n,n) - diag(ones(n-1,1),1) - diag(ones(n-1,1),-1)
Szybszym sposobem jest u»ycie funkcji toeplitz :
-->n=5; // pour
fixer une valeur a n...
-->toeplitz([2 -1 zeros(1,n-2)])
2. Je»eli
A
jest macierz¡
diagonalne macierzy
(n; n), diag(A)
zwróci wektor kolumnowy zawieraj¡cy elementy
A (a zatem otrzymamy wektor kolumnowy o wymiarze n).
n, w której elementy
tt diag(diag(A)) zwróci macierz kwadratow¡ diagonaln¡ o wymiarze
diagonalne b¦d¡ takie jak w macierzy wyj±ciowej.
3. Oto jedna z mo»liwo±ci :
--> A = rand(5,5)
--> T = tril(A) - diag(diag(A)) + eye(A)
4.(a)
--> Y = 2*X.^2 - 3*X + ones(X)
--> Y = 2*X.^2 - 3*X + 1 // wyko\.zystuj\k{a}c zapis skrócony
--> Y = 1 + X.*(-3 + 2*X) // oraz schemat Hornera
(b)
--> Y = abs(1 + X.*(-3 + 2*X))
(c)
--> Y = (X - 1).*(X + 4) // wyko\.zystuj\k{a}c zapis skrócony
(d)
--> Y = ones(X)./(ones(X) + X.^2)
--> Y = (1)./(1 + X.^2) // z skrótami
5. Oto skrypt :
n = 101;
// dyskretyzacja
x = linspace(0,4*%pi,n);
y = [1 , sin(x(2:n))./x(2:n)]; // aby zapobiec dzieleniu przez zero...
plot(x,y,"x","y","y=sin(x)/x")
6. Mo»liwe rozwi¡zanie (dla ró»nych warto±ci
n = 2000;
x = rand(1,n);
xbar = cumsum(x)./(1:n);
106
n) :
plot(1:n, xbar, "n","xbar", ...
"ilustracja lgn : xbar(n) -> 0.5 qd n -> + oo")
107
Dodatek B
Rozwi¡zania ¢wicze« z rozdziaªu 3
1. Klasyczny algorytm wyko»ystu¡cy dwie p¦tle :
function [x] = sol_tri_sup1(U,b)
//
// rozwi\k{a}zanie Ux = b gdzie U jest macierz\k{a} trójk\k{a}tn\k{a} górn\
//
[n,m] = size(U)
// kilka wyj\k{a}tków ....
if n ~= m then
error(' Macierz nie jest kwadratowa')
end
[p,q] = size(b)
if p ~= m then
error(' Wyraz wolny ma nieprawid\l{}owy wymiar')
end
// pocz\k{a}tek algorytmu
x = zeros(b) // rezerwuje miejsce dla x
for i = n:-1:1
suma = b(i,:)
for j = i+1:n
suma = suma - U(i,j)*x(j,:)
end
if U(i,i) ~= 0 then
x(i,:) = suma/U(i,i)
else
error(' Macierz jest nieodwracalna')
end
end
endfunction
A oto wersja wykorzystuj¡ca pojedy«cz¡ p¦tl¦
function [x] = sol_tri_sup2(U,b)
//
//
[n,m] = size(U)
// niektóre wyj\k{a}tki ....
if n ~= m then
error(' Macierz nie jest kwadratowa')
end
108
[p,q] = size(b)
if p ~= m then
error(' Wektor wyrazów wolnych ma z\l{}y wymiar)
end
// pocz\k{a}tek algorytmu
x = zeros(b) // rezerwuje miejsce dla x
for i = n:-1:1
suma = b(i,:) - U(i,i+1:n)*x(i+1:n,:) // zobacz komentarz ko\'ncowy
if U(i,i) ~= 0 then
x(i,:) = suma/U(i,i)
else
error(' Nie mo\.zna odwróci\'c macierzy')
end
end
endfunction
Komentarz : w pierwszej iteracji (dla
i = n) macierze U(i,i+1:n) et x(i+1:n,:) s¡ puste.
Odpowiadaj¡ one obiektom zdeniowanym w Scilabie (macierz pusta), które oznaczone s¡
przez
[].
2.
A = A + [].
suma = b(n,:).
Dodawanie macierzy pustej jest zdeniowane i daje :
pierwszej iteracji mamy
suma = b(n,:) + []
to znaczy
Zatem w
//
// skrypt rozwiazujacy x" + alpha*x' + k*x = 0
//
// Aby przeksztalcic rownanie do postaci ukladu rownan pierwszego rzedu
// kladziemy : X(1,t) = x(t) i X(2,t) = x'(t)
//
// Otrzymujemy wowczas : X'(t) = A X(t) z : A = [0 1;-k -alpha]
//
k = 1;
alpha = 0.1;
T = 20;
// moment koncowy
n = 100; // dyskretyzacja czasowa : przedzial [0,T] zostanie
// podzielony na n przedzialow
t = linspace(0,T,n+1); // momenty czasowe : X(:,i) bedzie korespondowal z
dt = T/n; // zmiana czasu
A = [0 1;-k -alpha];
X = zeros(2,n+1);
X(:,1) = [1;1]; // warunki poczatkowe
M = expm(A*dt); // oblicza exponent A dt
// obliczenia
for i=2:n+1
X(:,i) = M*X(:,i-1);
end
// wyswitlenie rezultatów
xset("window",0)
xbasc()
xselect()
plot(t,X(1,:),'czas','pozycja','Courbe x(t)')
xset("window",1)
xbasc()
xselect()
109
X(:,t(
plot(X(1,:),X(2,:),'pozycja','predkosc','Trajektoria w przestrzeni stanow')
3.
4.
function [i,info]=przedzial(t,x)
// poszukuje dychotomii przedzialu i takiej, ze: x(i)<= t <= x(i+1)
// jezeli t nie jest z przedzialu [x(1),x(n)] zwraca info = %f
n=length(x)
if t < x(1) | t > x(n) then
info = %f
i = 0 // kladziemy wartosc domyslna
else
info = %t
i_dolne=1
i_gorne=n
while i_gorne - i_dolne > 1
itest = floor((i_gorne + i_dolne)/2 )
if ( t >= x(itest) ) then, i_dolne= itest, else, i_gorne=itest, end
end
i=i_dolne
end
endfunction
function [p]=myhorner(t,x,c)
// rozwiniecie wielomianu c(1) + c(2)*(t-x(1)) +
// algorytmem Hornera
// t jest wektorem (lub macierza) momentów czasu
n=length(c)
p=c(n)*ones(t)
for k=n-1:-1:1
p=c(k)+(t-x(k)).*p
end
endfunction
c(3)*(t-x(1))*(t-x(2)) + ...
5. Rozwini¦cie w szereg Fouriera :
function [y]=signal_fourier(t,T,cs)
//
//
//
//
//
ta funkcja zwraca T-okresowy sygnal
t : wektor momentow dla których obliczmy
sygnal y ( y(i) odpowiadaj\k{a}cy t(i) )
T : okres sygnalu
cs : jest wektorem ktory wskazuje amplitude kazdej funkcji f(i,t,T)
l=length(cs)
y=zeros(t)
for j=1:l
y=y + cs(j)*f(j,t,T)
end
endfunction
function [y]=f(i,t,T)
// wielomiany trygonometryczne dla sygna\l{}u o okresie T :
// jesli i jest parzyste
: f(i)(t)=sin(2*pi*k*t/T) (z k=i/2)
// jesli i jest nieparzyste : f(i)(t)=cos(2*pi*k*t/T) (z k=floor(i/2))
110
// stad w szczególnosci f(1)(t)=1 jest traktowany ponizej
// jako przypadek szczegolny i niezbyt wa\.zny
// t jest wektorem mamentów czasowych
if i==1 then
y=ones(t)
else
k=floor(i/2)
if modulo(i,2)==0 then
y=sin(2*%pi*k*t/T)
else
y=cos(2*%pi*k*t/T)
end
end
endfunction
6. Spotkanie : niech
TA i TB
b¦d¡ momentami przybycia Pana A i Pani B. S¡ to dwie zmi-
U ([17; 18]) a spotkanie ma miejsce jezeli [TA ; TA +
1=6] [ [TB ; TB + 1=12] 6= ;. Doswiadczenie spotkania odpowiada realizacji zmienne losowej
wektorowej R = (TA ; TB ) która, zgodnie z hipotezami, ma rozkªad zero-jedynkowy na
kwadracie [17; 18] [17; 18]. Prawdopodobie«stwo spotkania wyznacza sie wi¦c w opar-
enne losowe niezale»ne o rozkªadzie
ciu o zale»no±¢ pomi¦dzy powie»chni¡ obszaru (odpowiadaj¡c¡ pojedynczemu spotkaniu)
zdeniowan¡ jako:
8
< TA TB + 1=12
6
: TTB;T TA2 +[171;=18]
A B
oraz powie»chni¡ kwadratow¡ (1), przez co otrzymuje sie
p = 67=288.
Aby obliczy¢
to prawdopodobie«stwo, mo»na przyj¡¢ ze spotkanie powinno miec miejsce pomi¦dzy
poªódniem a godzin¡ pierwsz¡. Poprzez symulacj¦ otrzymuje sie
m do±wiadcze« a praw-
dopodobie«stwo empiryczne jest liczb¡ przypadków w których spotkanie ma miejce podzielon¡
przez
m.
A oto rozwi¡zanie :
function [p] = rdv(m)
tA = rand(m,1)
tB = rand(m,1)
spotkanie = tA+1/6 > tB & tB+1/12 > tA;
p = sum(bool2s(spotkanie))/m
endfunction
mo»na tak»e wyko»ysta¢ funkcje
grand
opisan¡ w rozdziale dotycz¡cym zastosowa« :
function [p] = rdv(m)
tA = grand(m,1,"unf",17,18)
tB = grand(m,1,"unf",17,18)
spotkanie = tA+1/6 > tB & tB+1/12 > tA;
p = sum(bool2s(spotkanie))/m
endfunction
111
Dodatek C
Rozwi¡zania ¢wicze« z rozdziaªu 4
Czy to sprawka kostki?
Je»eli przez
J
J
ma
przy zaªo»eniu, »e kostka jest symetryczna.
W
oznaczymy zmienn¡ losow¡ b¦d¡c¡ wynikiem do±wiadczenia, wówczas
rozkªad geometryczny
G (p )
gdzie
p = 1 =6
ten sposób mo»emy okre±li¢ prawdopodobie«stwo poszczególnych zmiennych losowych jako
(przymujemy
q = 1 p = 5=6) :
P (J = 1) = p; P (J = 2) = qp; P (J = 3) = q2 p; ::::; P (J = 10) = q9 p; P (J > 10) = q10
W drugiej cz¦±ci tabeli podano cz¦sto±¢ wyst¦powania poszczególnych zmiennych losowych, co
w skrypcie zapiszemy nast¦puj¡co :
occ= [36 ; 25 ; 26 ; 27 ; 12 ; 12 ; 8 ; 7 ; 8 ; 9 ; 30];
p = 1/6; q = 5/6;
pr = [p*q.^(0:9) , q^10]';
y = sum( (occ - m*pr).^2 ./ (m*pr) );
y_progowy = cdfchi("X", 10, 0.95, 0.05);
mprintf("\n\r Test dla :")
mprintf("\n\r y = %g, et y_progowy (95 \%) = %g", y, y_progowy)
mprintf("\n\r 200*min(pr) = %g", 200*min(pr))
Otrzmujemy
y = 7:73915 gdy yseuil = 18:307, zatem kostka wydaje si¦ by¢ prawidªowa.
200 min(pr) ' 6:5 co jest znacznie poni»ej warunku pozwalaj¡cego
Niemniej jednak mamy
zastosowa¢ test (nale»aªoby wykona¢ jeszcze kilka dodatkowych do±wiadcze«).
Urna Polya
Funkcja scilaba
function [XN, VN] = Urna_Polya_rownolegla(N,m)
VN = ones(m,1) ; V_plus_R = 2 ; XN = 0.5*ones(m,1)
for i=1:N
u = grand(m,1,"de"f)
// losowanie jednej kuli
V_plus_R = V_plus_R + 1 // dodaje kule
ind = find(u <= XN)
// znajduje numer urny z której
// wylosowano kule zielona
VN(ind) = VN(ind) + 1
// zwiekszamy liczbe kul zielonych w tej urnie
XN = VN / V_plus_R
// aktualizujemy proporcje kul zielonych
end
endfunction
Skrypt Scilaba
// symulacja polya :
112
N = 10;
m = 5000;
[XN, VN] = Urna_Polya_rownolegla(N,m);
// 1/ obliczenie wartosci oczekiwanej i przedzialu ufnosci
EN = mean(XN);
// wartosc oczekiwana empiryczna
sigma = st_deviation(XN); // odchylenie standardowe empiryczne
delta = 2*sigma/sqrt(m); // zaokraglenie dla przedzialu empirycznego (2 dla 1.9599..)
mprintf("\n\r E teoretyczne = 0.5");
mprintf("\n\r E oszacowane = %g",EN);
mprintf("\n\r Przedzial (empiryczny) ufnosci przy 95\% : [%g,%g]",EN-delta,EN+delta);
// 2/ test chi2
alpha = 0.05;
p = 1/(N+1); // prawdopodobienstwo kazdego wyniku (rozklad jednostajny)
occ = zeros(N+1,1);
for i=1:N+1
occ(i) = sum(bool2s(XN == i/(N+2)));
end
if sum(occ) ~= m then, error(" Problem..."), end // mala poprawka
Y = sum( (occ - m*p).^2 / (m*p) );
Y_seuil = cdfchi("X",N,1-alpha,alpha);
mprintf("\n\r Test chi 2 : ")
mprintf("\n\r ----------- ")
mprintf("\n\r wielkosc otrzymana w tescie : %g", Y);
mprintf("\n\r wielkosc progowa : %g", Y_progowe);
if (Y > Y_progowe) then
mprintf("\n\r Wniosek : Hipoteza odrzucona !")
else
mprintf("\n\r Wniosek : Hipoteza nie odrzucona !")
end
// 3/ ilustracja graficzna
function [d] = gestosc_chi2(X,N)
d = X.^(N/2 - 1).*exp(-X/2)/(2^(N/2)*gamma(N/2))
endfunction
czestosc = occ/m;
ymax = max([czestosc ; p]); rect = [0 0 1 ymax*1.05];
xbasc(); xset("font",2,2)
subplot(2,1,1)
plot2d3((1:N+1)'/(N+2), czestosc, style=2 , ...
frameflag=1, rect=rect, nax=[0 N+2 0 1])
plot2d((1:N+1)'/(N+2),p*ones(N+1,1), style=-2, strf="000")
xtitle("Czestosci empiryczne (kreski pionowe) i prawdopodobienstwa teoretyczne (krzy\.zyk
subplot(2,1,2)
// rysujemy g\k{e}sto\'s\'c chi2 ???a N ddl
X = linspace(0,1.1*max([Y_seuil Y]),50)';
D = densite_chi2(X,N);
plot2d(X,D, style=1, leg="densite chi2", axesflag=2)
// kreski pionowe dla Y
plot2d3(Y, densite_chi2(Y,N), style=2, strf="000")
xstring(Y,-0.01, "Y")
// kreski pionowe dla Yseuil
plot2d3(Y_seuil, densite_chi2(Y_seuil,N), style=5, strf="000")
xstring(Y_seuil,-0.01, "Yseuil")
xtitle("Pozycja Y w odniesieniu do warto\'sci Yseuil")
Poni»ej przedstawiono rezultaty otrzymane dla
E dok\l{}adne = 0.5
113
N = 10 et m = 5000 (patrz wykres (C.1)) :
E oszacowane = 0.4959167
Przedzia\l{} ufno\'sci dla 95% : [0.4884901,0.5033433]
Test du chi 2 :
-------------warto\'s\'c otrzymana w te\'scie : 8.3176
warto\'s\'c progowa : 18.307038
Wniosek : Hipoteza nie odrzucona !
Rysunek C.1: Ilustracja dla testu
2 urny Polya...
Most ?brownien?
Funkcja
function [X] = most_brownien(t,n)
X = sum(bool2s(grand(n,1,"def") <= t) - t)/sqrt(n)
endfunction
Skrypt
Skrypt ten wykonuje
m symulacji zmiennej losowej Xn (t), przedstawia wykres funkcji rozkªadu
n = +1) i
empirycznego, nakªadaj¡c na niego wykres funkcji rozkªadu oczekiwanego (dla
wreszcie oblicza test KS :
t = 0.3;
sigma = sqrt(t*(1-t)); // oczekiwane odchylenie standardowe
n = 4000;
// n "du\.ze"
m = 2000;
// licczba symulacji
X = zeros(m,1);
// zainicjowanie wektora realizacji
for k=1:m
X(k) = most_brownien(t,n); // p\k{e}tla licz\k{a}ca kolejne realizacje
end
// wykres funkcji rozk\l{}adu empirycznego
X = - sort(-X); // tri
prcum = (1:m)'/m;
xbasc()
plot2d2(X, prcum)
x = linspace(min(X),max(X),60)';
// odci\k{e}te i
[P,Q]=cdfnor("PQ",x,0*ones(x),sigma*ones(x)); // rz\k{e}dne dla funkcji dok\l{}adenj
plot2d(x,P,style=2, strf="000")
// rzutujemy je na wykres pocz\k{a}tkowy
// zastosowanie testu KS
alpha = 0.05;
FX = cdfnor("PQ",X,0*ones(X),sigma*ones(X));
Dplus = max( (1:m)'/m - FX );
Dminus = max( FX - (0:m-1)'/m );
Km = sqrt(m)*max([Dplus ; Dminus]);
K_progowe = sqrt(0.5*log(2/alpha));
// prezentacja wyników
//
mprintf("\n\r Test KS : ")
mprintf("\n\r -------- ")
114
mprintf("\n\r warto\'s\'c
mprintf("\n\r warto\'s\'c
if (Km > K_progowe) then
mprintf("\n\r Wniosek :
else
mprintf("\n\r Wniosek :
end
Oto rezultaty otrzymane dla
otrzymana w te\'scie : %g", Km);
progowa : %g",K_seuil);
Hipoteza odrzycona !")
Hipoteza nie odrzucona !")
n = 1000 i m = 4000 :
Test KS :
-------warto\'s\'c otrzymana w te\'sci : 1.1204036
warto\'s\'c progowa : 1.2212382
Wniosek : Hipoteza nie odrzucona !
115
Download