Laboratorium metod numerycznych - SCILAB Laboratorium 2 W najprostszym przypadku, Scilab jest wykorzystywany jako kalkulator zdolny wykonywać obliczenia na wektorach i macierzach. W prostych zadaniach raczej nie ma potrzeby pisania programów. Dosyć szybko jednak korzystać będziemy ze skryptów (zbiorów instrukcji, poleceń Scilaba), a następnie funkcji. Wprowadzony język programowania, dzięki operowaniu na systemie macierzowym, jest prostym, ale potężnym i efektywnym narzędziem. Za pomocą dowolnego edytora tekstowego można utworzyć plik ( pusty plik tekstowy) o dowolnej nazwie i rozszerzeniu (tzw. skrypt) zawierający wiele poleceń, które zachowują się jak program - są interpretowane w miarę wczytywania kolejnych poleceń z pliku przez Scilab. Zwyczajowo plikom zawierającym skrypty nadajemy rozszerzenie.sce. Podobnie jest z rozszerzeniem.sci, które zwyczajowo przypisywane jest plikom zawierającym funkcje. Scilab wyposażony jest w edytor SciPad, który rozpoznaje składnię poleceń Scilaba i odpowiednio koloruje słowa kluczowe. Można w nim pisać programy i funkcje oraz od razu przesyłać je do uruchomienia w Scilabie. Uruchamiamy go z menu (pozycja Editor ). Na początku skryptu umieszczamy polecenie clear w chwili uruchamiania skryptu obecne w pamięci zmienne znikną (te z poprzednich uruchomień programu). Jeśli nasz program rysuje jakieś wykresy to umieszczenie na początku polecenia xdel(winsid()) spowoduje zamknięcie wszystkich otwartych okien graficznych. Polecenie clc czyści ekran konsoli. Zmienne predefiniowane zaczynają się od znaku % {%pi, %e, %i, %inf, %t, %f}. Zmienne te nie ulegają usunięciu po wydaniu komy clear. Po zakończeniu wykonywania poleceń ze skryptu (czy wpisywanych z klawiatury) wszystkie nowo utworzone zmienne pozostają w pamięci i są dostępne do dalszych operacji, dzięki temu kiedy coś nam nie wychodzi można sprawdzić np. czy utworzone wektory są wierszowe czy kolumnowe i jakie mają rozmiary (za pomocą polecenia whos() ). Komentarze zaczynają się od dwóch znaków // i rozciągają się do końca wiersza. Istnieje także możliwość wykomentowania większej liczby wierszy -> po zaznaczeniu fragmentu tekstu należy wybrać z menu Edit polecenie Comment selection, co spowoduje wpisanie znaków // na początku każdego wiersza. Istnieje oczywiście polecenie Uncomment selection. Wykonanie skryptu Scilaba znajdującego się w bieżącym katalogu następuje po wywołaniu w terminalu Scilaba polecenia exec i wpisaniu nazwy pliku np. exec skrypt.sce lub exec ('skrypt.sce'). Zostanie wówczas wyświetlona, a potem wykonana zawartość pliku. Po nazwie pliku zawierającego skrypt można wprowadzić liczbę określającą tryb wykonywania skryptu. Jeśli nie chcemy wyświetlania zawartości używamy formy exec( skrypt.sce,0). W przypadku dłuższych poleceń lub skryptów wykorzystujemy SciPad i po zapisaniu pliku na dysk z menu Execute edytora wybieramy pozycje załadowania do Scilaba. 1
Przykład.1 Uruchamiamy w Scilabie edytor. Wprowadzamy poniższy kod generujący i wyświetlający funkcję sinusa: // wyczyszczenie pamięci xdel(winsid()); //wyczyszczenie (zamknięcie) wszystkich okien graficznych clc; //wyczyszczenie konsoli t=linspace(0, 2*%pi, 100); //(obliczenie od 0 do 2pi, liczba iteracji=100) y=sin(t); // funkcja którą liczymy, czyli sinus plot2d(t,y) // wygenerowanie wykresu liczonej funkcji y=f(t) Plik zapisujemy w katalogu roboczym (d:\student\nazwisko\scilab) pod nazwą sinus.sce. Z menu edytora wybieramy pozycję 'wykonaj'. Przykład.2 Utworzyć i wykonać skrypt o poniższym kodzie. Zapisać pod nazwą funkcja.sce w katalogu roboczym. Wykonanie skryptu wykonujemy przez wywołanie w terminalu polecenia exec ('funkcja.sce'). Przetestować tryby wykonywania skryptu {exec ('funkcja.sce',0), exec ('funkcja.sce',1)} Jest to skrypt do wygenerowana wykresu funkcji e -x sin(4x) ze zmiennym za każdym razem rozmiarem przedziału [a; b] i liczbą podprzedziałów. // wyczyszczenie pamięci xdel; //wyczyszczenie aktualnej grafiki clc; //wyczyszczenie konsoli a=input(" Podaj lewy kraniec przedziału : "); b=input(" Podaj prawy kraniec przedziału : "); n=input(" Podaj ilość podprzedziałów : "); x=linspace(a,b,n+1); // obliczenie odciętych y=exp(-x).*sin(4*x); // obliczenie rzędnych plot(x,y,"b") // rysunek funkcji b oznacza kolor blue charakterystyki xtitle("y=exp(-x)*sin(4*x)","y","x") Funkcje W przeciwieństwie do skryptów funkcje mogą przyjmować parametry i zwracać wyniki. Również zapisywane są w plikach. W jednym pliku można umieścić wiele funkcji, każda z funkcji musi zaczynać się słowem kluczowym function, kończyć function. Wbudowane i dostępne są właściwie wszystkie funkcje elementarne (są już skompilowane). Funkcje trygonometryczne proste, odwrotne, hiperboliczne... (argumenty tych funkcji są w radianach). Funkcje logarytmiczne: log logarytm naturalny, log10 logarytm dziesiętny, log2 logarytm o podstawie 2. Funkcja eksponencjalna: exp. Liczby losowe: funkcja rand(n1,n2) generuje macierz n1 n2 składającą się z liczb losowych z przedziału <0,1). Istnieje też generator liczb losowych grand umożliwiający uzyskanie różnych zadanych rozkładów. Funkcje specjalne: erfc, funkcja gamma, funkcje Bessela pierwszego i drugiego rodzaju, Definiowanie funkcji w pliku : function [sinus,cosinus] = moja_funkcja(x) sinus = sin(x); cosinus = cos(x); function W tym przypadku funkcja przyjmuje pojedynczy parametr, a zwraca wierszowy wektor dwuelementowy (jeśli argumentem będzie wektor funkcja zwróci macierz, składającą się z dwóch wektorów wynikowych funkcji sin i cos). Definiowanie funkcji w linii kom: deff('[si,co]=moja_fun(x)',['si=sin(x)','co=cos(x)']) Tak zdefiniowana funkcja działa identycznie jak ta zdefiniowana w pliku. Można używać jej również jako argumentu dla innych funkcji. Ogólnie składnia tego polecenia/definicji jest następująca: deff(łańcuch_składni,wektor_łańcuchów_poleceń) (ten ostatni wektor może by wierszowy lub kolumnowy). Po wektorze łańcuchów poleceń może wystąpić jeszcze jeden argument pojedynczy znak 'c' lub 'n' pierwszy z nich (jest to wartość domyślna) oznacza, że funkcja ma zostać skompilowana, a drugi że nie. Przy przedstawionym sposobie zdefiniowania funkcji moja_fun wywołanie jej musi mieć postać [a,b] = moja_fun(x) tzn. po lewej stronie musi występować wektor (z nawiasami kwadratowymi), gdybyśmy chcieli tego uniknąć 2
moglibyśmy zdefiniować tą funkcję nieco inaczej: deff('sico=moja_fun(x)',['sico(1)=sin(x)','sico(2)=cos(x)']) Jeżeli wynikiem funkcji ma być pojedyncza zmienna nawiasy kwadratowe nie są konieczne. Tak zdefiniowaną funkcję można wywołać tak: ab = moja_fun(x) i ab będzie wektorem dwuelementowym. Pierwszy sposób definiowania funkcji, choć mniej wygodny przy definiowaniu, poprawnie działa także gdy argument x jest macierz, a drugi nie. Wywoływanie funkcji normalne w linii kom, z podaniem nazwy zmiennej, której ma zostać przypisany wynik lub bez jej podania. Za pomoc polecenia feval(x,y,f) gdzie x i y są wektorami argumentów (w przypadku funkcji jednej zmiennej może być tylko jeden) a f jest nazwą funkcji (wcześniej zdefiniowanej lub wczytanej z pliku). Polecenie to oblicza wartości funkcji f podstawiając do niej kolejno wartości z wektorów argumentów - dzięki temu działa nawet jeśli funkcja f została zdefiniowana w taki sposób, że nie działała dla argumentów będących wektorami. Kompilowanie funkcji w Scilabie realizowane jest na bieżąco. Przykład.3 W edytorze wprowadź poniższy kod. Plik zapisz jako funkcja.sci. function faza = f(x) faza = sin(x*%pi/10) function W konsoli Scilaba wywołaj polecenie: exec('funkcja.sci'); x = -10:0.1:10; faza = f(x); plot2d(x,faza) Podstawowe konstrukcje języka Scilab Instrukcja if: if wyrażenie logiczne then polecenia elseif wyrażenie logiczne then polecenia... Części elseif i else są opcjonalne. Instrukcja for: for zmienna = (dowolnie zdefiniowany wektor lub macierz) polecenia dodatkowe Instrukcja while: while wyrażenie logiczne polecenia Część else jest opcjonalna, polecenia występujące w niej są wykonywane gdy wyrażenie logiczne stanie się fałszywe. Instrukcja select/case: select wyrażenie case wyrażenie1 then polecenia... case wyrażenie n-te then polecenia Część else jest opcjonalna. Przykłady: Zapisz podane kody w oddzielnych skryptach lub testuj bezpośrednio w konsoli Scilaba. // if-else, zastosowanie // definiujemy macierz mającą na głównej przekątnej 2 // a na sub- i super-przekątnych -1 for i= 1:3, for j = 1:3 if i == j then a(i,j) = 2; elseif abs(i-j) == 1 then a(i,j) = -1; else a(i,j) = 0; // koniec if-else // koniec for // koniec for // select-case lepsze niż if-else przy wielu przypadkach W zależności od wartości liczby punkty zmienna ocena przyjmuje podane wartości 5,4,3,2 3
jeśli nie zajdzie żaden z tych przypadków wówczas jest 1. punkty= 95; select floor(punkty/10) case 9 then ocena = 5 case 8 then ocena = 4 case 7 then ocena = 3 case 6 then ocena = 2 else ocena= 1 {Funkcja floor zaniża otrzymaną z obliczeń wartość do najbliższej liczby całkowitej} //select while %t do n=round(510*rand(1,1)) select n case 0 then disp(0) case 1 then disp(1) else break //while e=1; a=1; k=1; while norm(a-(a+e),1) > %eps, e=e/2; k=k+1; e,k = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Wykresy SCILAB posiada możliwość prezentacji wyników w postaci wykresów 2D lub 3D. Do kreślenia wykresów płaskich służy rodzina poleceń plot2d (plot2d1, plot2d2, plot2d3 i plot2d4), do wykresów trójwymiarowych służy polecenie plot3d. Do zarządzania formą graficzną okna z wykresami służy polecenie xset. Opisy wykresu i osi realizuje polecenie xtitle, a legę polecenie leg. Ostatnim poleceniem używanym przy realizacji wykresów jest subplot, dzielące okno graficzne na części umożliwiając wyświetlenie kilku wykresów. Podstawowe polecenie kreślenia wykresu 2D ma postać: plot2d(a); Wykreślany jest wykres liniowy utworzony na podstawie danego wektora a, którego wartości stanowią współrzędną tworzonego wykresu. Za współrzędne x przyjmowane są wartości odpowiadające kolejnym współrzędnym wartości wektora a. Jeżeli konieczne jest także określenie wartości na osi Ox stosuje się polecenie w postaci: plot2d(a,b); Dodatkowo można zdefiniować parametry wykreślanego wykresu, takie jak: kolor wykresu - definiuje się kolor kreślonej krzywej, wartości zestawiono w tabeli. plot2d(t,sin(t),3); wartość 1 2 3 4 5 6 7 8 9 10 kolor Czarny Niebieski zielony niebieski2 czerwony Różowy czerwony2 Biały granatowy granatowy2 styl punktowania - zamiast krzywej wyświetlane są punkty o wybranym kształcie, parametr przyjmuje wartości od -1 do -10 plot2d(t,sin(t),-3); 4
skale na osi można zdefiniować jako normalną (równomierną) - n, lub logarytmiczną - l. Po słowie kluczowym logflag wpisuje się kombinację dwóch parametrów n l. np.: plot2d(t,sin(t)logflag= "nn "); // Obie osie normalne plot2d(t,sin(t),logflag= "ln "); // Oś x logarytmiczna parametr frameflag decyduje o zakresie wyświetlania osi współrzędnych, przyjmuje wartości od 0 do 8. Wartość domyślna 8. parametr axes flag ustawia sposób wyświetlania osi i ramki, przyjmuje wartości od 0 do 5. opis poszczególnych przebiegów można na wykresie umieścić za pomocą polecenia leg, opis pojawia się na dole pod wykresem. plot2d(t,sin(t),leg= "sin(t)"); plot2d(t,[cos(t) sin(t)],leg= "sin(t)@cos(t)"); Istnieją cztery dodatkowe polecenia z rodziny plot2d: plot2d1 - wykresy logarytmiczne plot2d2 - wykres schodkowy plot2d3 - wykres impulsowy plot2d4 - wykres wektorowy Wykresy 3D są kreślone za pomocą polecenia plot3d(x,y,z), gdzie x i y są wektorami definiującymi współrzędne punktów wykresu na osiach Ox i Oy, a z jest macierzą wartości przyjmowanych na osi Oz dla poszczególnych punktów na płaszczyźnie Oxy. Powierzchnia generowanego wykresu jest jednokolorowa. Chcąc uzyskać powierzchnie z koloryzacją zgodną z wartościami kreślonej funkcji, należy użyć polecenia plot3d1(x,y,z). subplot - służy do dzielenia okna graficznego na mniejsze obszary, umożliwia to umieszczenie w oknie graficznym kilku wykresów obok siebie. Jako parametry ustawia się m liczbę kolumn, n liczbę wierszy m numer podokna graficznego, subplot(mnl) lub subplot(m,n,l). POLECENIA DO WYKONANIA 1. Zapoznać się z edytorem SciPad. Zmienić ustawienia językowe (options/locale) na język polski. 2. Ustalić aktualny katalog roboczy polecenie chdir('ścieżka'). Można też skorzystać z menu (pozycja File i dalej Change Directory ). 3. Wykonać wszystkie przykłady z instrukcji. Po wykonaniu obliczeń należy zmienić zmienne wartości (np. liczbę iteracji, zakresy przedziału liczenia funkcji...) 4. Utworzyć samodzielnie skrypt generujący wykres funkcji y=14*cos(12*sin(2*x))+2. 5. Utworzyć samodzielnie skrypt w którym po wprowadzeniu dowolnej wartości kąta (x) wyliczy funkcję średniej arytmetycznej czterech składników: sin(x), cos(x), tg(x) i ctg(x). 6. Utworzyć samodzielnie skrypt impedancja.sce, który będzie wyznaczał wartość zastępczej impedancji szeregowo połączonych elementów RLC, przy zmiennych wartościach częstotliwości. 7. Napisać skrypt wykreślający przebiegi sygnałów sinusoidalnego, sinusoidalnego wyprostowanego jednopołówkowo, sinusoidalnego wyprostowanego dwupołówkowo. Okno graficzne podzielić na trzy części w poziomie, do każdego dodać opisy wykresów, osi. Każdy przebieg kreślony innym kolorem oraz dodatkowo umieścić na wykresach punkty obliczeniowe. 8. Utworzyć skrypt, który wypełnia losowymi liczbami całkowitymi macierz NAZWISKO o strukturze 4x3. Przedstawić wartość min i max w tej macierzy. Przy błędnym działaniu programu, zapętleniu w obliczeniach lub zawieszeniu proszę przerwać proces liczenia (menu control/abort). 5