23

3. Tworzenie skryptów i współpraca z plikami danych

Skrypt

jest

m-plikiem zawierającym ciąg poleceń. Zawsze na początku skryptu powinien występować komentarz dokładnie opisujący działanie skryptu. Komentarz rozpoczyna się od znaku %. Ze względu na zachowanie uniwersalności pisanych programów w Matlabie wskazane jest używanie w komentarzu tylko znaków ASCII, nawet jeżeli system operacyjny komputera pozwala pisać polskie litery. Przeniesienie skryptu z polskimi literami na komputer nie tolerujący polskich ogonków, uczyni komentarz zupełnie nieczytelnym.

Komentarz jest dostępny za pomocą polecenia help z nazwą skryptu jako parametrem, np. dla skryptu o nazwie axb.m należy podać polecenie help axb

Zmienne i wyrażenia występujące w pliku skryptowym mają charakter globalny i są dostępne w dowolnej linii realizowanego programu obliczeń. Zwykle skrypt jest tworzony dla wielokrotnie powtarzalnych obliczeń, łatwiejszego wprowadzania większej ilości danych czytanych z plików zewnętrznych, czy też wyprowadzania wyników do plików zewnętrznych.

W przypadku wprowadzania danych z klawiatury w skrypcie wykorzystuje się funkcję input, np.

a = input(‘Podaj z klawiatury wartosc a = ‘);

Po napotkaniu instrukcji input wyświetlany jest na ekranie łańcuch stanowiący argument wejściowy funkcji input, a następnie Matlab oczekuje na wprowadzenie liczby z klawiatury.

Do wyprowadzania wyników obliczeń na ekran wykorzystuje się funkcję disp, np.

disp(‘Wynik obliczen wynosi’); disp(wynik);

W przypadku dużej liczby danych i wyników można przy pisaniu skryptu korzystać z funkcji save oraz load.

Wszystkie zmienne w przestrzeni roboczej Matlaba można zapisać na dysku w aktualnym katalogu poleceniem

save nazwa_pliku

Zmienne zapisywane są w tym przypadku na dysku w pliku o rozszerzeniu *.mat.

Zmienne występujące w przestrzeni roboczej zapamiętywane są w kodzie wewnętrznym, nieczytelnym dla użytkownika.

Pominięcie nazwy pliku, czyli podanie samego polecenia

save

24

powoduje, że wszystkie zmienne są zapamiętane w pliku o nazwie domyślnej matlab.mat , utworzonym w aktualnym katalogu.

Jeżeli mają być zapamiętane jedynie wybrane zmienne, to należy po nazwie pliku dodać nazwy tych zmiennych

save nazwa_pliku zmienna1 zmienna 2 zmienna3

Przykładowy skrypt zapamiętujący zmienne na dysku w pliku *.mat

% m-plik o nazwie savemat.m

% - zawiera tresc skryptu savemat

% - ilustruje zapamietywanie zmiennych na dysku w pliku *.mat

% Uruchomienie skryptu savemat wymaga:

% - wybrania katalogu nazimi.prn : cd:\nazimi.prn

% - wprowadzenia z klawiatury polecenia: savemat

% UWAGA ! Polecenie nie moze zawierac rozszerzenia *.m

disp(' Skrypt savemat');

disp(' - tworzy macierz Z o elementach zespolnych:');

disp(' Z = [1+2i 3+4i; 5+6i 7+8i];');

disp(' - wyswietla elementy macierzy Z'); disp(Z);

disp(' - zapisuje macierz Z na dysku w pliku maczespZ.mat:'); disp(' save maczespZ Z;');

Z = [1+2i 3+4i; 5+6i 7+8i];

save maczespZ Z;

disp('...');

disp(' Plik maczespZ.mat zapisano w aktualnym katalogu'); disp(' koniec skryptu savemat');

Po wykonaniu skryptu w aktualnym katalogu zostanie utworzony plik o nazwie maczespZ.mat. Wartości zapamiętanych zmiennych w pliku *.mat mogą być wykorzystane przez inne skrypty za pomocą polecenia

load nazwa_pliku

Jeśli nazwa pliku zostanie pominięta to w wyniku polecenia load

zostaną odczytane wszystkie dane z pliku matlab.mat.

Przykładowy skrypt czytający zmienne zapamiętane na dysku w pliku *.mat

% m-plik o nazwie loadmat.m

% - zawiera tresc skryptu loadmat

% - skrypt ilustruje czytanie z dysku zmiennych

% zapisanych na dysku w pliku *.mat

% Uruchomienie skryptu loadmat wymaga:

25

% - wybrania katalogu nazimi.npr za pomoca polecenia

% cd:\nazimi.npr

% - wprowadzenia z klawiatury polecenia

% loadmat

% UWAGA ! Polecenie nie moze zawierac rozszerzenia *.m

disp(' Skrypt loadmat');

disp(' - czyta z pliku maczespZ.mat macierz zespolona Z'); load maczespZ;

disp(' - zapamietuje wczytana macierz jako Z1');

Z1=Z;

disp(' - wyswietla elementy macierzy Z1');

disp(Z1);

disp(' - mnozy macierz przez liczbe 10: Z2=Z1*10;');

Z2=Z1*10;

disp(' - wyswietla elementy wynikowej macierzy Z2');

disp(Z2);

disp(' koniec skryptu loadmat');

Jeżeli użytkownik chce mieć możliwość podglądu lub edytowania wartości zapamiętywanych na dysku, to powinien skorzystać z opcji zapamiętywania zmiennych w kodzie ASCII. Podanie opcji

-ascii

powoduje zapamiętanie zmiennych w postaci znakowej, z użyciem 8 cyfrowego zapisu liczb

save nazwa_pliku zmienna1 zmienna 2 zmienna3 -ascii

Zapisane zmienne tworzą tablice liczb umieszczonych jedna pod drugą, a nazwy zmiennych są pomijane. Zapamiętane dane mogą być wykorzystane w innych skryptach za pomocą polecenia

load

nazwa.rozszerzenie

Wczytywane są wartości zapamiętane w pliku tekstowym o podanej nazwie z rozszerzeniem. Dane muszą tworzyć tablicę prostokątną. Wczytane dane zostaną zapamiętane w macierzy o nazwie takiej jak nazwa pliku, np.

load

A.dat

powoduje zapamiętanie wczytanych danych w macierzy o nazwie A.

Polecenie

load nazwa_pliku –acsii

umożliwia wczytanie macierzy z pliku tekstowego, którego nazwa nie zawiera rozszerzenia. Podanie samej nazwy pliku bez opcji –ascii powoduje poszukiwanie pliku binarnego. Dane muszą tworzyć tablicę prostokątną.

26

Przykładem skryptu czytającego dane, rozwiązującego układ równań liniowych i zapisującego uzyskane wyniki na dysk komputera jest skrypt pliku axb.m. Skrypt rozwiązuje następujący układ równań liniowych

10x1 + 2x2 + 3x3 = 1

4x1 + 50x2 + 6x3 = 2

7x1 + 8x2 + 90x3 = 3

W skrypcie wykorzystano zapis macierzowy układu równań w postaci

Ax

= b

gdzie

A - macierz kwadratowa o wymiarze n razy n,

b - wektor kolumnowy o n elementach.

Przykładowy skrypt czytający i zapisujący zmienne na dysku w kodzie ASCII

% axb

% Skrypt jest zapamietany w pliku axb.m

% Uruchomienie skryptu polega na wprowadzeniu polecenia

% axb

% Skrypt axb.m, macierze A, b wystepuja w tym samym katalogu.

% Opis skryptu jest wyswietalny na ekranie

disp(' Skrypt rozwiazuje uklad liniowych rownan A*x=b'); disp(' A - macierz kwadratowa, b - wektor kolumnowy');

disp(' x - wektor kolumnowy rozwiazan');

disp(' Rozwiazanie jest wyznaczane za pomoca polecenia'); disp(' x = A\b');

disp(' Przyklad');

disp(' 10*x1 + 2*x2 + 3*x3 = 1');

disp(' 4*x1 + 50*x2 + 6*x3 = 2');

disp(' 7*x1 + 8*x2 + 90*x4 = 3');

disp(' Macierz A zapamietano w kodzie ASCII w pliku A.dat'); disp(' 10 2 3');

disp(' 4 50 6');

disp(' 7 8 90');

disp(' Wektor b zapamietano w kodzie ASCII w pliku b.dat'); disp(' 1');

disp(' 2');

disp(' 3');

disp(' Macierz A jest wczytana jako plik ASCII A.dat’); load A.dat;');

disp(' Wektor b jest wczytany jako plik ASCII b.dat’); disp(' Wektor x jest zapisany jako plik ASCII x.dat');

% Polecenia skryptu

load A.dat; % wczytany plik zostanie zapamietany jako macierz A disp(' Wczytana macierz wspolczynnikow ukladu rownan A');

27

disp(A); % macierz A zostanie wyswietlona na ekranie

load b.dat; % wczytany plik zostanie zapamietany jako wektor b disp(' Wczytany wektor prawej strony ukladu rownan b');

disp(b);% wektor b zostanie wyswietlony na ekranie

x = A\b;

disp(' Wyznaczono rozwiazanie ukladu rownan x = A\b');

disp(x); % wektor x zostanie wyswietlony na ekranie

save 'x.dat' x -ascii; %rozwiazanie x zapisano w pliku x.dat disp(' Zapamietano rozwiazanie w pliku x.dat');

disp('koniec obliczen realizowanych przez skrypt axb');

% koniec skryptu axb.m

Skrypt

axb może być wykorzystany do rozwiązywania dowolnego układu równań liniowych. W tym celu należy:

• skierować ścieżkę Matlaba do własnego katalogu roboczego, np. cd c:\nazimi.npr,

• za pomocą edytora ASCII przepisać treść skryptu axb do pliku axb.m, z pominięciem fragmentów dotyczących przykładowego układu równań,

• za pomocą edytora ASCII utworzyć we własnym katalogu plik A.dat zawierający macierz A ze współczynnikami rozwiązywanego układu równań,

• za pomocą edytora ASCII utworzyć we własnym katalogu plik b.dat zawierający wektor b prawych stron układu równań,

• uruchomić skrypt przez wpisanie w oknie poleceń Matlaba instrukcji axb,

• za pomocą polecenia dir sprawdzić, czy po wykonaniu skryptu w aktualnym katalogu został utworzony plik x.dat,

• wyświetlić na ekranie zawartość pliku x.dat za pomocą polecenia type x.dat

Rozwiązywanie zadań elektrotechnicznych w Matlabie wymaga często korzystania z algorytmów składających się nie tylko z działań arytmetycznych, ale przede wszystkim z logicznych wyborów, realizowanych za pomocą instrukcji strukturalnych.

W Matlabie występują następujące instrukcje sterujące działaniem programu:

• iteracyjne: for, while

• warunkowa: if

• uzupełniające: break, return

Instrukcja iteracyjna for

Instrukcja

for ma postać

28

for zmienna=wyrażenie

instrukcje

end

Pętla for służy do powtarzania wyszczególnionych instrukcji zawartych pomiędzy for i end określoną liczbę razy. Wyrażenie występuje często w postaci wektora x:y, w którym poszczególne kolumny mogą być zwykłymi skalarami, np.

for

i=1:n

instrukcje

end

Pętle for mogą być wzajemnie zagnieżdżane.

% Tworzenie macierzy przy pomocy instrukcji for

n=5; m=10;

for i=1:n

for

j=1:m

A(i,j)=i+j-1;

end

end

disp('Utworzono macierz A');

disp('Liczba wierszy n'), disp(n);

disp('Liczba kolumn m'), disp(m);

disp('Elementy macierzy A'), disp(A);

Instrukcja warunkowa if

Instrukcja

if ma postać

if wyrażenie_logiczne

instrukcje1

elseif wyrażenie_logiczne2

instrukcje2

else

instrukcje3

end

Występowanie elseif oraz else jest opcjonalne. Ponadto może wystąpić kilka instrukcji elseif. W wyrażeniach logicznych stosowane są operatory logiczne.

% Tworzenie macierzy quasidiagonalnej

% przy pomocy instrukcji for oraz if

n=input('Podaj liczbe wierszy n = ');

m=input('Podaj liczbe kolumn m = ');

29

b=input('Podaj wartosc elementu na diagonali b = ');

for i=1:n

for

j=1:m

if

i==j

A(i,j)=b;

elseif

abs(i-j)==1

A(i,j)=-1;

else

A(i,j)=0;

end

end

end

disp('Macierz A'),disp(A);

Instrukcja iteracyjna while

Instrukcja

while ma postać

while wyrażenie_warunkowe

instrukcje

end

Instrukcje między

while i end

są wykonywane dopóki wartość

wyrażenia_warunkowego ma wartość true, tzn. gdy macierz będąca wartością wyrażenia_logicznego posiada wszystkie elementy niezerowe. Pętla while jest zatem wykonywana nieokreśloną z góry liczbę razy. Przerwanie pętli while umożliwia instrukcja break.

% skrwhile.m

% exp(x) = 1+ x + x^2/2 + x^3/3 + ...

eps=1e-3; % dokladnosc obliczen

a=3; % wartosc dla ktorej nalezy obliczyc exp

x=a; y=1; k=1;

while x >= eps

k=k+1; y=y+x; x=x*a/k;

end

expad=exp(a); % obliczenia wg funkcji Matlaba exp()

expap=y; % obliczenia przyblizone wg wzoru iteracyjnego

bladobl=(expap-expad)/expad*100; % procentowy blad obliczen disp(' Obl. dokladne exp(a) = ');

expad

disp(' Obl. wg wzoru iteracyjnego exp(a)=1+a+a^2/2+ ...=); expap

disp(' Procentowy blad obliczen przyblizonych bladobl = '); bladobl

30

Instrukcja

break

Opuszczenie

pętli for lub while przed zakończeniem jej wykonania może być dokonane za pomocą break. W przypadku pętli zagnieżdżonych użycie break powoduje przejście do pętli nadrzędnej.

%Wyznaczenie dokladnosci komputera przy pomocy for oraz break eps=1;

for i=1:10000

eps=eps/2;

if(eps+1<=1)

break

end

end

eps=eps*2;

disp('Dokladnosc komputera wynosi'); disp(eps);

Instrukcja

return

Instrukcja

pomocnicza

return powoduje opuszczenie danego skryptu lub funkcji, a następnie powrót do jego/jej wywołania (normalnie funkcja jest opuszczana po jej wykonaniu).

Zadania do samodzielnego rozwiązania

Zadanie

1

Dane jest zespolona macierz admitancji węzłowych

 45 − j45

− 25 + j25

0







Y = G + jB = − 25 + j25 50 − j50 − 25 + j25 (3.1)



0

− 25 + j25

25 − j25 





oraz zespolony wektor prądów węzłowych



0







I = I

jI

(3.2)

a +

b = 

0



 0.1 − j 





1

Należy we własnym katalogu zapamiętać część rzeczywistą G macierzy admitancji w pliku G.dat oraz część urojoną B - w pliku B.dat. Podobnie należy postąpić z wektorem prądów węzłowych.

Następnie utworzyć skrypt o nazwie uyi.m, realizujący następujące działania:

• czytanie z dysku macierzy G oraz B,

• tworzenie zespolonej macierzy admitancji węzłowych Y = G+jB ,

31

• czytanie z dysku wektorów Ia oraz Ib,

• tworzenie zespolonego wektora prądów węzłowych I = Ia + jIb ,

• rozwiązanie układu równań liniowych Y U = I ,

• wydzielenie części rzeczywistych i urojonych napięć węzłowych U = Ua + jUb

• zapisanie na dysku wartości wyliczonych napięć węzłowych w plikach Ua.dat oraz Ub.dat

Zadanie 2

Napisać skrypt tworzący zespoloną macierz admitancji węzłowych w oparciu o wczytane z klawiatury numery węzłów początkowych i końcowych oraz admitancje gałęzi liniowego obwodu elektrycznego pokazanego na rys. 3.1. Utworzyć macierz wp - numerów węzłów początkowych gałęzi, wk - numerów węzłów końcowych gałęzi, g - konduktancji gałęzi, b - susceptancji gałęzi.

(1-j2)S

2

(1.5-j2)S

1

3

(1-j2.5)S

(2-j3)S

(2-j2)S

0

4

(1-j2)S

5

(0.5-j2.5)S

Rys. 3.1. Schemat liniowego obwodu elektrycznego z numerami węzłów i admitancjami gałęzi.

Węzeł o numerze 0 jest węzłem odniesienia.

Do tworzenia macierzy admitancji węzłowych wykorzystać następujące instrukcje j=sqrt(-1); ygal=g+j*b; nbr=length(ygal);

for k=1:nbr

i=wp(k); j=wk(k); y=ygal(k);

if i*j > 0

Y(i,i)=Y(i,i)+y; Y(i,j)=-y;

Y(j,j)=Y(j,j)+y; Y(j,i)=-y;

end

if i==0 Y(j,j)=Y(j,j)+y; end

if j==0 Y(i,i)=Y(i,i)+y; end

end

Utworzoną zespoloną macierz admitancji zapisać na dysku w pliku macY.mat.