Professional Documents
Culture Documents
Roman Salomon - 'Matlab' - Podstawy I Zastosowania
Roman Salomon - 'Matlab' - Podstawy I Zastosowania
ROMAN SALAMON
MATLAB
PODSTAWY I ZASTOSOWANIA
POLITECHNIKA GDAŃSKA
WYDZIAŁ ELEKTRONIKI, TELEKOMUNIKACJI
I INFORMATYKI
KATEDRA ELEKTRONIKI MORSKIEJ
GDAŃSK 2008
2
Skrypt objęty jest prawem autorskim. Prawa autorskiego nie narusza korzystanie z jego wersji
elektronicznej oraz jednokrotny wydruk części lub całości skryptu do użytku prywatnego
przez studentów Wydziału Elektroniki, Telekomunikacji i Informatyki Politechniki Gdań-
skiej. Pozostałe formy wykorzystania skryptu wymagają pisemnej zgody autora.
SPIS TREŚCI
1. WPROWADZENIE .......................................................................................................................... 5
1. WPROWADZENIE
Program MATLAB, zwany również często „środowiskiem MATLAB”, przezna-
czony jest do obliczeń inżynierskich i naukowych oraz do wizualizacji ich wyników. W śro-
dowisku MATLAB obowiązuje język, w którym komunikujemy się z programem polecając
mu wykonywanie określonych zadań. Jest to język wysokiego poziomu, co w praktyce ozna-
cza, że w formie prostej instrukcji można wyrazić polecenie wykonania bardzo złożonego
zadania. Cechą charakterystyczną języka MATLAB jest to, że podstawową formą danych
jest w nim macierz rzeczywista bądź zespolona. Dane i wyniki obliczeń są przechowywane w
przestrzeni roboczej i istnieją w niej dopóki nie zostaną usunięte przez użytkownika, bądź
przez zamknięcie programu. Zmienne nie są deklarowane.
Środowisko MATLAB jest otwarte w tym sensie, że użytkownik ma dostęp do jego
funkcji, poleceń i bibliotek oraz może tworzyć własne pliki i funkcje. Program daje także
możliwość współpracy z innymi programami, np. Excel, C, Fortran.
Program MATLAB może być instalowany na praktycznie dowolnym komputerze.
Zmiana platformy sprzętowej nie wiąże się z utratą własnego oprogramowania.
Oprócz podstawowego programu MATLAB istnieją tzw. Toolboxy, które są zawierają
specjalistyczne oprogramowanie z kilkunastu dziedzin nauki i techniki. Podstawowy pakiet
MATLAB można także uzupełnić interaktywnym programem SIMULINK, który służy do
modelowania i symulacji systemów dynamicznych, a w tym systemów elektronicznych, tele-
komunikacyjnych i systemów automatyki.
Niniejszy skrypt został pomyślany jako pomoc dydaktyczna do przedmiotu „Technika
Obliczeniowa i Symulacyjna”, prowadzonego na Wydziale Elektroniki, Telekomunikacji i
Informatyki Politechniki Gdańskiej dla studentów drugiego semestru kierunku Elektronika i
Telekomunikacja. Składa się on z dwóch części; w pierwszej omówione są podstawy użytko-
wania programu MATLAB, zaś w drugiej – praktyczne przykłady zastosowania programu w
elektronice i telekomunikacji. Pisząc ten skrypt autor zakładał, że Czytelnik po raz pierwszy
spotyka się z programem MATLAB oraz że Jego wiedza i umiejętności odpowiadają pro-
gramowi pierwszego semestru studiów. Jedynie w drugiej części skryptu występują przykłady
dotyczące treści przekazywanych na drugim lub wyższych latach studiów.
Materiał zawarty w skrypcie wystarcza do wykonania projektu i ćwiczeń laboratoryj-
nych z przedmiotu „Technika Obliczeniowa i Symulacyjna” w zakresie związanym z użytko-
waniem programu MATLAB.
Dążąc do zmniejszenia objętości skryptu ograniczono przede wszystkim liczbę omó-
wionych funkcji i instrukcji, rezygnując z rzadziej używanych i bardziej skomplikowanych.
Dużą część praktycznych zadań można wykonać bez używania tych pominiętych funkcji i
instrukcji, aczkolwiek ich stosowanie ułatwia niewątpliwie programowanie. Ponadto opis
omawianych instrukcji i funkcji często nie jest kompletny. Pominięto z zasady te możliwości
zawarte w instrukcjach i funkcjach, które znajdują względnie rzadko praktyczne zastosowa-
nie. Funkcjonowanie prawie każdej instrukcji zilustrowano przykładem, co powinno ułatwić
jej pełne zrozumienie, zapamiętanie i dalsze stosowanie we własnych programach.
Autor wyraża nadzieję, że skrypt ułatwi opanowanie przedmiotu i zachęci do głębszego
poznania programu MATLAB, a w przyszłości do jego stosowania w czasie studiów i pracy
zawodowej.
6
2. INFORMACJE WSTĘPNE
2.1. Przygotowanie programu MATLAB ® do pracy
Na pulpicie monitora znajduje się ikona programu MATLAB®, której przyciśnięcie le-
wym klawiszem myszy powoduje uruchomienie programu. Pojawia się najpierw na krótką
chwilę logo programu MATLAB®, a następnie okno programu. Okno to może zawierać różne
wewnętrzne okna, w zależności od wcześniejszego ustawienia przez poprzedniego użytkow-
nika. W naszej pracy z programem MATLAB® używać będziemy dwóch okien, a mianowicie
okna podstawowego okna Command Window oraz okna Workspace.
W celu uaktywnienia tych okien wybieramy na górnym pasku View i na rozwiniętej li-
ście zaznaczamy wyżej wymienione nazwy okien. Pożądany widok oka programu MATLAB ®
zawiera po lewej stronie okna Workspace, a po prawej stronie okno Command Window. Prze-
ciągając myszą prawe obramowanie pionowe lewego okna można mu nadać pożądaną szero-
kość – około 1/3 szerokości prawego okna. Okno Command Window wykorzystujemy do
wprowadzania wszystkich instrukcji, komend, danych itp. W oknie Workspace pojawiają się
natomiast sukcesywnie informacje o wszystkich stałych i zmiennych używanych w pisanym
przez nas programie. W kolumnie Name widoczne są użyte symbole stałych i zmiennych, a
obok ich wymiar. Obserwując to okno unikamy niezamierzonego używania tych samych sym-
boli w odniesieniu do innych zmiennych. Użyteczna jest również informacja o wymiarach
zmiennych, która pozwala unikać błędów związanych z niezachowaniem reguł matematycz-
nych obowiązujących w programie MATLAB®. Widok obu okien pokazano na rys. 2.1.
1
Popularny styl Times New Roman ma trudną do odróżnienia literę l i cyfrę 1, co może być przyczyną
błędów w programie.
9
der w katalogu Work i w tym folderze umieszczać swoje skryptu. W tym celu należy wykonać
kolejno następujące czynności:
w pasku okna Untitled wybrać File
z menu File wybrać Save As…
pojawia się okno, w którym na górnym pasku wybieramy ikonę Utwórz nowy folder
w oknie pojawia się ramka, w której wpisujemy nazwę użytkownika i wciskamy En-
ter
przyciskamy ikonę nowego folderu i wpisujemy w dolnej ramce nazwę naszego pro-
gramu, która nie zawiera polskich liter
w oknie nazwanym dotąd Untitled pojawia się tytuł C:\MATLAB\work\nazwa użyt-
kownika\nazwa skryptu.m
Sprawdzamy, czy ścieżka dostępu do naszego skryptu jest prawidłowa i dokonujemy
ewentualnych poprawek opisaną wyżej metodą. Nazwa skryptu ma nadane automatycznie
rozszerzenie .m. Nazwy skryptów z takim rozszerzeniem są traktowane w programie MA-
TLAB® jako zbiory instrukcji przeznaczonych do wykonania.
W otwartym oknie o podanej wyżej nazwie tworzymy nasz program. Pracę rozpoczy-
namy od wpisania nagłówka, którym powinna być (dla porządku) nazwa naszego skryptu.
Wpisujemy ją następująco: ‘nazwa’ (bez kropki). Każdy tekst zwarty między apostrofami ‘’
napisany jest kolorem czerwonym i jest widoczny po uruchomieniu naszego programu w
oknie Command Window. Następnie wpisujemy kolejne instrukcje według zasad podanych w
dalszej części skryptu. Po zakończeniu każdego etapu pracy można postępować w dwojaki
sposób. Jeżeli chcemy zapisać skrypt bez sprawdzania jego poprawności wówczas, po ciśnię-
ciu File, wybieramy w menu polecenie Save lub wciskamy ikonę Save. Jeżeli chcemy jedno-
cześnie sprawdzić działanie naszego programu, wówczas wciskamy na pasku etykietę Debug i
w widocznym menu wybieramy komendę Save and Run. Analogiczny efekt daje wciśnięcie
klawisza F5. Nasz program zostanie zapisany i jednocześnie uruchomiony. Skutki urucho-
mienia programu i jego działanie omówimy w dalszej części skryptu.
Po zapisaniu programu można zakończyć jego użytkowanie przez zamknięcie jego okna
lub kontynuować pracę nad programem. Usilnie zaleca się okresowe zapisywanie programu,
w celu uniknięcia jego utraty w wyniku niewłaściwych działań lub zawieszenia się wykony-
wania programu MATLAB® .
Zapisany i zamknięty skrypt można otworzyć w celu dalszej pracy nad nim lub w celu
uruchomianie zawartego w nim programu. Należy w tym celu na pasku okna programu MA-
TLAB® przycisnąć ikonę Open File i z wybrać z katalogu Work folder z nazwą użytkownika, a
w nim nazwę skryptu. Inny sposób otwarcia skryptu polega na wpisaniu w oknie Command
2
Window polecenia :
>> open <nazwa skryptu>
Jeżeli, przykładowo, nasz skrypt ma nazwę wykres, to odpowiednia komanda ma nastę-
pujący zapis:
>> open wykres
Polecenie jest wykonywane tylko wtedy, gdy w Current Directory wpisana jest właściwa
ścieżka dostępu do naszego skryptu. Zwykle wpisany jest jedynie katalog Work i wtedy należy
2
Symbole < > oznaczają tu i w dalszym tekście miejsce, w którym programista wpisuje ciągi znaków,
których znaczenie wpisano między symbolami.
10
uzupełnić ścieżkę wciskając sąsiednią ikonę Browse for Folder i wybierając z niej nazwę fol-
deru użytkownika.
Po wykonaniu czynności opisanych w powyższej instrukcji można przystąpić do pisania
programu. Aby jednak nasz program funkcjonował zgodnie z naszymi intencjami, konieczne
jest poznanie podstawowych zasad obowiązujących w programie MATLAB® . Przedstawimy
je w następnym rozdziale.
Program zwraca ścieżkę dostępu do danej funkcji, którą można wykorzystać do jej
otwarcia. Niestety, w wypadku plików umieszczonych w podkatalogach katalogu Work, trzeba
podać ścieżkę dostępu w Current Directory.
what
Powyższe polecenie powoduje pojawienie się wszystkich plików znajdujących się w
bieżącym katalogu, do którego ścieżka podana jest w Current Directory.
Niepotrzebne pliki i obiekty graficzne usuwamy poleceniem
delete <nazwa pliku>
Usunąć można pliki, do których dostęp podany jest w Current Directory.
close
Powyższe polecenie zamyka okno otwartego rysunku. Jeżeli chcemy zamknąć wszyst-
kie rysunku, to dajemy polecenie
close all
Polecenia dotyczące przestrzeni roboczej
clear
Polecenie to usuwa z przestrzeni roboczej wszystkie zmienne. Polecenie uzupełnione o:
clear x,y,z,... – usuwa wymienione zmienne
clear global – usuwa zmienne globalne
clear functions – usuwa funkcje
clear all – usuwa zmienne lokalne, globalne i funkcje.
Listę bieżących zmiennych występujący w przestrzeni roboczej otrzymujemy pisząc
who
Pełną informację o tych zmiennych daje polecenie
whos
Przypominamy, że lista zmiennych znajduje się również w oknie Workspace.
12
>> a=2*3
a=
6
>> a=2/3
a=
0.6667
>> a=2^3
a=
8
Liczby mogą być również wyrażone jako wartość funkcji:
>> a=sin(2)
a=
0.9093
>> a=log10(2)
a=
0.3010
Zauważmy, że po wpisaniu wartości liczby, program MATLAB® zwraca jej wartość w
stosownym formacie. Bardzo często jest to niewygodne, zwłaszcza, gdy wyniki pośrednich
obliczeń są liczne i nie interesują użytkownika. W celu uniknięcia tej niedogodności, instruk-
cję kończymy znakiem ; . Mamy wtedy:
>> a=2^3;
lecz wartość zmiennej a pozostaje w pamięci, co sprawdzamy pisząc
>> a
a=
8
ans =
0.9093
>> imag(a)
ans =
0.1411
>> conj(a)
0.9093 - 0.1411i
W wypadku, kiedy próbujemy wykonać operację, której wynikiem nie jest określona
liczba, program MATLAB® daje ostrzeżenie lub sygnalizuje błąd. Przykładem jest dzielenie
liczby przez zero:
>> 1/0
Warning: Divide by zero.
(Type "warning off MATLAB:divideByZero" to suppress this warning.)
ans =
Inf
Wynikiem operacji jest nieskończoność zapisywana tu jako Inf.
Inny przykład to dzielenie 0/0:
>> 0/0
Warning: Divide by zero.
(Type "warning off MATLAB:divideByZero" to suppress this warning.)
ans =
NaN
Skrót NaN (od ang. Not a Number) oznacza, że wynik nie ma formy liczbowej.
Problemów takich można uniknąć wykorzystując w instrukcjach liczbę oznaczoną jako
eps. Jest to bardzo mała liczba o wartości równej przedziałowi kwantyzacji liczb obwiązują-
cemu w obliczeniach. Zastosowanie tej liczby ilustruje przykład wyznaczania wartości funkcji
sinx/x w punkcie x=0. W punkcie tym występuje dzielenie 0/0, lecz funkcja jest ciągła i ma
wartość 1. Zapiszmy zatem
>> x=0;
>> sin(x)/x
Warning: Divide by zero.
(Type "warning off MATLAB:divideByZero" to suppress this warning.)
ans =
NaN
>> x=0+eps;
>> sin(x)/x
ans =
1
W drugiej instrukcji do argumentu dodaliśmy eps, w wyniku czego otrzymaliśmy pra-
widłowy wynik. Wartość eps wynosi w tym wypadku
>> eps
ans =
2.2204e-016
Funkcja floor zaokrągla liczbę do najbliższej liczby całkowitej, najbliższej minus nie-
skończoności.
>> floor(2.7)
ans =
2
Funkcja ceil zaokrągla liczbę do najbliższej liczby całkowitej, najbliższej nieskończono-
ści.
>> ceil (-2.7)
ans =
-2
Funkcja fix zaokrągla liczbę do najbliższej liczby całkowitej, najbliższej zeru.
>> fix(2.7)
ans =
2
Jakkolwiek wyniki zaokrąglenia przy użyciu różnych funkcji bywają jednakowe, to
każda z nich może być przydatna.
Każda z wymienionych funkcji może mieć argument zespolony, a wówczas sposób
uśredniania odnosi się oddzielnie do części rzeczywistej i urojonej liczby. Przykładowo:
>> floor(2.7-i*2.7)
ans =
2.0000 - 3.0000i
A=
0.9501 0.6068 0.8913 0.4565 0.8214
0.2311 0.4860 0.7621 0.0185 0.4447
Liczby zawarte w macierzy o rozkładzie normalnym mają wartość średnią zmierzającą
do zera i odchylenie standardowe zmierzające do jedności.
>> A=randn(2,5)
A=
-0.4326 0.1253 -1.1465 1.1892 0.3273
-1.6656 0.2877 1.1909 -0.0376 0.1746
Szczegóły dotyczące praktycznego wykorzystania tych macierzy podamy w dalszej czę-
ści skryptu.
Na zakończenie omawiania sposobów definiowania macierzy pokażemy jeszcze jedną
użyteczną metodę. Polega ona na sklejaniu macierzy o tej samie liczbie wierszy lub kolumn.
Metodę te pokazują następujące przykłady:
>> A=zeros(3,4)
A=
0 0 0 0
0 0 0 0
0 0 0 0
>> B=ones(3,3)
B=
1 1 1
1 1 1
1 1 1
>> C=[A B A]
C=
0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 1 1 1 0 0 0 0
Ze zdefiniowanych macierzy A i B utworzona została macierz C o liczbie wierszy rów-
nej liczbie wierszy macierzy A i B i zwiększonej liczbie kolumn.
Jeżeli macierze mają jednakową liczbę kolumn, to można z nich utworzyć macierz o
zwiększonej liczbie wierszy:
>> C=[A(:,1:3);B;A(:,1:3)]
C=
0 0 0
0 0 0
0 0 0
1 1 1
1 1 1
1 1 1
0 0 0
0 0 0
0 0 0
W macierzy A zmniejszyliśmy liczbę kolumn do trzech stosując wcześniej podany za-
pis. Należy zwrócić uwagę, że macierze w instrukcji zostały rozdzielone średnikiem.
Dogodnym narzędziem wprowadzania zmian istniejącej macierzy jest Array Editor. Jest
to okno, w którym edytowana jest macierz i w którym można zmieniać wartości elementów
macierzy, liczbę wierszy i kolumn oraz wpisywać w nie nowe wartości. Okno to otwiera in-
strukcja
openvar(‘A’)
20
N
C(m, k ) A(m, n)B(n, k) dla m=1:M i k=1:K;
n1
Zdefiniowane wyżej macierze A i B nie mogą być mnożone, bo liczba kolumn macierzy
A nie jest równa liczbie wierszy macierzy B. Rzeczywiści mamy:
>> C=A*B
??? Error using ==> *
Inner matrix dimensions must agree.
Możliwe jest natomiast wykonanie mnożenia macierzy A przez macierz transponowaną
B’.
>> B'
ans =
2 6
4 7
-4 -3
>> C=A*B'
C=
26 40
-38 -35
Użyteczną operacją w obliczeniach jest mnożenie wektora kolumnowego przez wektor
wierszowy. Mamy bowiem wtedy:
N
C(m, k ) A(m,1)B(1, k) A(m,1)B(1, k) dla
n1
m=1:M i k=1:K;
B=
3 4
6 5
>> C=A*B
C=
15 14
42 41
>> D=B*A
D=
19 26
26 37
Jak widać, przestawienie kolejności macierzy daje różna wyniki, gdyż C≠D.
2 3 4 5 x 1 28
4 4 8 2 x 2 4
3 3 4 2 x 3 7
2 2 3 5 x 4 13
3.3. Tablice
Program MATLAB® operuje nie tylko na macierzach, lecz również na tablicach (ang.
arrays). Tablicą (dwuwymiarową) jest uporządkowany w wiersze i kolumny zbiór liczb lub
znaków. W tym sensie macierz jest specyficzną tablicą numeryczną, której dotyczą operacje
macierzowe. Specyficzną formą tablic zawierających znaki (ang. charakter arrays) są rów-
nież łańcuchy (ang. strings). W skrypcie zajmiemy się wyłącznie tablicami numerycznymi i
łańcuchami, które mają duże znaczenie z punktu widzenia obliczeń inżynierskich.
>> C=A.^3
C=
1 8 27
27 8 1
64 125 216
Ze względu na sposób wykonywania operacji na tablicach nie są wykonywane niektóre
operacje odnoszące się do macierzy. Przykładowo porównajmy dwie operacje, w których
występuje wcześniej zdefiniowana macierz A:
>> B=[1 2 3]'
B=
1
2
3
>> C=A*B
C=
14
10
32
>> C=A.*B
??? Error using ==> .*
Matrix dimensions must agree.
Pierwsza operacja odnosi się do macierzy i jest poprawna. Druga operacje dotyczy ta-
blic i jest błędna, gdyż obie tablice muszą mieć jednakowy wymiar.
Podane wyżej przykłady dotyczyły tablic kwadratowych. Obowiązują one również dla
tablic prostokątnych, a w tym jednowymiarowych, odpowiadających wektorom. Pokazuje to
następujący przykład:
>> a=1:10
a=
1 2 3 4 5 6 7 8 9 10
>> b=a.^2
b=
1 4 9 16 25 36 49 64 81 100
Zauważmy, że operacja potęgowania jest równoważna mnożeniu. Jeżeli zapiszemy:
>> b=a^2
??? Error using ==> ^
Matrix must be square.
program MATLAB® zgłosi błąd i wskaże na jego przyczynę, która wynika z reguł mnożenia
macierzy (przy mnożeniu a·a=a2 macierz a musi być prostokątna).
W programie MATLAB® można posługiwać się tablicami wielowymiarowymi (ang.
multidimesional arrays). Sposób definiowania takich tablic i posługiwania się nimi pokażemy
w dalszej części skryptu.
3.3.2. Łańcuchy
Łańcuchy wykorzystywane są w prostych obliczeniach inżynierskich głównie do opi-
sywania danych i rysunków. Łańcuch znaków tworzymy ujmując je w apostrofy. Program
MATLAB® sygnalizuje pojawienie się początku łańcucha standardowo kolorem niebieskim, a
jego zakończenie zmianą koloru na czerwony. Łańcuchy wyróżniają się zatem wyraźnie w
pisanym przez użytkownika programie. Każdy znak łańcucha traktowany jest jako element
tablicy, co umożliwia wykonywanie na nich określonych operacji. Kilka prostych operacji
ilustruje poniższy przykład.
26
>> a='dom'
a=
dom
>> a(3)
ans =
m
>> a(2)='y'
a=
dym
W pierwszym wierszu poleceń zdefiniowany został łańcuch, w drugim wywołano trze-
cim element tego łańcuch, a w trzecim zmieniono znak o na znak y.
Łańcuchy można rozszerzać analogicznie jak macierze. Ilustruje to poniższy przykład
>> b='ek'
b=
ek
>> c=[a b]
c=
dymek
Rozdzielnie łańcuchów znakiem średnika powoduje utworzenie tablicy pod warunkiem,
że oba łańcuch mają jednakową liczbę znaków:
>> d='ogień'
d=
ogień
>> e=[c;d]
e=
dymek
ogień
3.4. Funkcje
Program MATLAB® dysponuje wielką liczbą funkcji, z których niewielka część jest
znana z ogólnej matematyki, a pozostała została zdefiniowana w programie w celu rozwiązy-
wania rozmaitych problemów numerycznych i tworzenia grafiki. Nawet pobieżna prezentacja
funkcji występujących w programie MATLAB® zdecydowanie przekracza ramy tego skryptu.
Ograniczymy się zatem do podania ogólnych zasad posługiwania się funkcjami i omówimy
najczęściej stosowane.
Dla potrzeb tego skryptu wygodnie jest podzielić funkcje na kilka charakterystycznych
typów i omówić je oddzielnie.
>> y=sin(x)
Praktyczny sposób wykorzystanie tej instrukcji pokazuje następujący przykład:
>> x=2*pi*(0:0.1:1)
x=
Columns 1 through 7
0 0.6283 1.2566 1.8850 2.5133 3.1416 3.7699
Columns 8 through 11
4.3982 5.0265 5.6549 6.2832
>> y=sin(x)
y=
Columns 1 through 7
0 0.5878 0.9511 0.9511 0.5878 0.0000 -0.5878
Columns 8 through 11
-0.9511 -0.9511 -0.5878 -0.0000
1 2 3
-1 3 4
-5 0 1
>> a=sum(A)
a=
-5 5 8
Jeżeli argumentem funkcji sum jest wektor, to zwraca ona sumę elementów tego wek-
tora. Tak więc sumę wszystkich elementów macierzy A wyznaczamy jako:
>> as=sum(a)
as =
8
lub bezpośrednio jako:
>> as=sum(sum(A))
as =
8
Bardzo użyteczną funkcją jest cumsum, która jest w obliczeniach numerycznych odpo-
wiednikiem całki
t
y( t ) x()d .
0
Funkcja ta wyznacza macierz, w której wierszach znajdują się bieżące sumy wyzna-
czane oddzielnie w każdej kolumnie według następującego wzoru:
m
B(m, n) A(m, n) .
n1
Jeżeli argument jest wektorem, to funkcja max wyznacza maksymalną wartość tego
wektora:
>> amax=max(a)
amax =
4
Zauważmy, że w tym przykładzie liczba 4 jest wartością maksymalną występującą w
macierzy A. W celu wyznaczenia wartości maksymalnej macierzy można użyć krótszej in-
strukcji:
>> amax=max(max(A))
amax =
4
Funkcja min zwraca wektor wierszowy, w którym znajdują się minimalne wartości wy-
stępujące w odpowiednich kolumnach. Oto przykład:
>> a=min(A)
a=
-5 0 1
>> amin=min(a)
amin =
-5
Funkcja mean zwraca wektor wierszowy, w którym znajdują się średnie wartości licz
występujących w odpowiednich kolumnach. Dla rozpatrywanej to macierzy mamy:
>> a=mean(A)
a=
-1.6667 1.6667 2.6667
>> amean=mean(a)
amean =
0.8889
Ostatnia liczba jest średnią wartością elementów macierzy A.
Funkcja std zwraca wektor wierszowy, w którym znajdują się odchylenia standardowe
wartości w odpowiednich kolumnach.
>> a=std(A)
a=
3.0551 1.5275 1.5275
Funkcja var wyznacza wariancję według podanych wyżej reguł:
>> a=var(A)
a=
9.3333 2.3333 2.3333
Jak widać, wariancja jest równa kwadratowi odchylenia standardowego. W wypadku
ostatnich funkcji nie podano odchylenia standardowego i wariancji wyznaczonego z wekto-
rów, gdyż nie są te wielkości równe i odpowiednim wielkościom dla całej macierzy.
Funkcji mean, std i var używa się głównie do analizy procesów stochastycznych.
Bardzo użyteczną funkcją jest funkcja size, która zwraca liczbę wierszy i kolumn ma-
cierzy:
>> [M,N]=size(A)
M=
3
N=
3
31
Na pierwszy rzut oka wydaje się ona zbędna, jednakże w bardziej złożonych progra-
mach wykorzystuje się ją bardzo często. Wymiary macierzy bywają bowiem zmienne, gdyż
mogą być uzależnione od podawanych przez użytkownika parametrów.
1 0 1
0 0 0
>> C3=A>=B
C3 =
0 1 1
1 1 1
0 1 1
Jeżeli chcemy znać wartości elementów macierzy A lub B, dla których zapisana relacja
jest prawdziwa możemy użyć mnożenia tablicowego (wyraz po wyrazie). Przykładowo rela-
cję równości spełniają w obu macierzach następujące elementy:
>> D=A.*C1
D=
0 2 0
0 3 0
0 0 1
Opis rzadziej używanych operatorów logicznych (np. and lub or) można znaleźć w Help
programu MATLAB.
Wszystkie podane wyżej relacje dotyczą również wektorów o tej samej liczbie elemen-
tów. Można je wykorzystywać m.in. do analizy przebiegu funkcji, rozwiązywania równań
nieliniowych itp.
Przydatną funkcją, w której występują relacje jest funkcja find. Zwraca ona numery
wierszy i kolumn w których dana relacja jest prawdziwa. Ilustruje to następujący przykład:
>> [m,n]=find(D>1)
m=
1
2
n=
2
2
Elementy macierzy D o wartościach większych od 1 to D(1,2) i D(2,2).
>> if w>2
y=2*w
end
>> y=3*w
y=
6
Warunkiem wykonania instrukcji y=2w jest to, że w>2; a ponieważ nie jest to prawda,
więc program wykonał pierwszą instrukcję znajdującą się za end i podał jej wynik.
Instrukcje warunkowe mogą być rozbudowane w celu zwiększenia liczby relacji logicz-
nych, których prawdziwość warunkuje wykonanie większej liczby instrukcji. Struktura takich
instrukcji warunkowych ma następującą postać:
if <relacja logiczna 1>
<instrukcja 1>
eleseif <relacja logiczna 2>
<instrukcja 2>
else
<instrukcja 3>
end
Polecenie elseif może powtarzać się wielokrotnie. Polecenie else może być użyte jedno-
krotnie lub być pominięte.
Jeżeli relacja 1 zapisana za if jest prawdziwa, program wykonuje instrukcję 1 i po jej
wykonaniu przechodzi do pierwszej instrukcji po end. W przeciwnym wypadku przechodzi do
polecenia elseif i sprawdza zapisaną relację 2. Jeżeli jest ona prawdziwa, to wykonuje instruk-
cję 2 i po jej wykonaniu przechodzi do pierwszej instrukcji za end. Jeżeli relacja 2 nie jest
prawdziwa, program wykonuje instrukcję 3 znajdującą się za poleceniem else i po jej wyko-
naniu przechodzi od instrukcji znajdującej się za end.
Należy podkreślić, że instrukcje 1, 2 i 3 mogą składać się z całych, rozbudowanych
fragmentów programu.
Wykorzystując relację równości == można sprawdzać zgodność łańcuchów, pod wa-
runkiem, że mają taką samą długość:
a =’kot’
if a=='kot'
'ssak'
elseif a=='kos'
'ptak'
end
ans =
ssak
Poniżej podano przykład programu, który na żądanie użytkownika wyznacza wartości
funkcji sin, cos, log, exp dla wektora x.
clear
x=1:5;
'Wpisz jedną z funkcji; sin, cos, log, exp.'
f=input('f= ');
if f=='sin'
y=sin(x)
elseif f=='cos'
y=cos(x)
elseif f=='log'
y=log10(x)
34
else
y=exp(x)
end
Po uruchomieniu programu mamy:
ans =
Wpisz jedną z funkcji; sin, cos, log, exp.
f= 'sin'
y=
0.8415 0.9093 0.1411 -0.7568 -0.9589
Należy zwrócić uwagę, że nazwy funkcji należy ująć w apostrofy.
Po następnym uruchomieniu programu i wybraniu innej funkcji otrzymujemy:
ans =
Wpisz jedną z funkcji; sin, cos, log, exp.
f= 'log'
y=
0 0.3010 0.4771 0.6021 0.6990
specjalną instrukcją. Przy długich programach może to być przyczyną błędów, gdyż można
przypadkowo użyć tej samej nazwy do oznaczenia innych zmiennych. Często w jednym pro-
gramie wykorzystuje się inne programy, które nie są zdefiniowane jako funkcje. Prawdopodo-
bieństwo popełnienia opisanego błędu rośnie wtedy jeszcze bardziej.
Zmienne lokalne występujące w funkcjach nie są widziane poza nimi. Można zatem
używać w programie tych samych nazw zmiennych, które występują w pliku zawierającym
funkcję. Jest to duże ułatwienie dla programisty. Aby funkcja nie była hermetycznie odcięta
od innych programów, konieczne jest stworzenie mechanizmów wprowadzających dane do
funkcji i umożliwiających pobieranie wyników.
Po tych ogólnych informacjach omówimy teraz podstawowe zasady tworzenia funkcji.
Każdy plik definiujący funkcję musi na początku pierwszego wiersza zawierać deklara-
cję function (program pisze ją automatycznie niebieskim kolorem), a następnie zapis funkcji.
Oto prosty przykład definiowania funkcji liniowej y=ax+b:
function u=prosta(v,m,n)
u=m*v+n;
Instrukcje te piszemy w nowym otwartym oknie skryptów (biała kartka na pasku narzę-
dziowym). Następnie wciskamy przyciskamy File i wybieramy z listy poleceń Save As… Do
katalogu Work (lub własnego foldera w katalogu Work) wpisujemy nazwę pliku, która musi
być identyczna jak nazwa funkcji. Plik zawierający funkcję prosta będzie zatem nosił nazwę:
prosta.m.
Zapiszmy teraz w oknie Command Window następujące dwie instrukcje:
>> x=0:10;
>> y=prosta(x,2,3)
y=
3 5 7 9 11 13 15 17 19 21 23
Program zwrócił wartości funkcji y=2x+3. Zauważmy, że w powyższych instrukcjach
użyto innych nazw zmiennych niż w definicji funkcji prosta. Nie ma to znaczenia, gdyż w
zapisie funkcji liczą się wyłącznie pozycje zmiennych.
Dla sprawdzenia czy zmienna v występująca w funkcji jest widoczna poza nią na-
piszmy:
>> v
??? Undefined function or variable 'v'.
Widoczna jest natomiast zmienna globalna x:
>> x
x=
0 1 2 3 4 5 6 7 8 9 10
Można tworzyć funkcje, które mają kilka zmiennych, parametrów liczbowych lub łań-
cuchów. W podanym wyżej przykładzie mamy jedną zmienna i dwa parametry liczbowe.
Funkcja może zwracać także pewną liczbę wyników – zmiennych wyjściowych. Zapis funkcji
jest wtedy bardziej złożony. Pokazuje to zamieszczony wyżej przykład funkcji liniowej, uzu-
pełniony o wyznaczanie kąta nachylenia prostej. Funkcja realizująca te zadania ma następu-
jącą składnię:
function [u,p]=prosta(v,m,n)
u=m*v+n;
p=180*atan(m)/pi
Jeżeli w oknie Command Window napiszmy następujące dwie instrukcje, to otrzymamy:
36
>> x=0:10;
>> [y,nachylenie]=prosta(x,2,3)
y=
3 5 7 9 11 13 15 17 19 21 23
nachylenie =
63.4349
Nachylenie prostej wynosi 63.40.
W podanych wyżej przykładach wpisywaliśmy w instrukcji używającej funkcji t ę samą
liczbę zmiennych, która występowała w definicji funkcji. W niektórych funkcjach nie ma
nieraz potrzeby podawania wszystkich zmiennych występujących w instrukcji. Podobnie nie
zachodzi także zawsze potrzeba zwracania wszystkich zmiennych wyjściowych. Wprowa-
dzono dwie funkcje, które zwracają liczbę zmiennych wejściowych i wejściowych, co wyko-
rzystuje się w programie funkcji. Liczbę zmiennych wejściowych podaje funkcja nargin, zaś
liczbę zmiennych wyjściowych – funkcja nargout.
Argumentami funkcji mogą być liczby, pojedyncze litery lub łańcuchy znaków. Jak to
powiedziano wyżej użytkownik nie musi podawać wszystkich parametrów wejściowych i
wymagać wszystkich wyników. W takich sytuacjach w zapisie definiowanej funkcji poda-
jemy ogólne nazwy argumentów, a mianowicie varargin i varargout. Definicja funkcji ma wów-
czas następującą postać:
function varargout=prosta(varargin)
Częściej jednak stosuje się zapisy mieszane, np.:
function [y,varargout]=prosta(x,varargin)
Podane wyżej ogólne zapisy funkcji są używane przez zaawansowanych użytkowników
Programu MATLAB . Dlatego ograniczamy się do zasygnalizowania ich istnienia, a zainte-
resowanych szczegółami odsyłamy do podanej literatury lub MATLAB Help.
Jeżeli funkcja ma być dostępna tylko w tworzonym programie, można się posłużyć in-
nym sposobem jej definiowania, a mianowicie funkcją inline. Instrukcja inline odnosi się wy-
łącznie do funkcji opisanych wyrażeniami matematycznymi zawierającymi operacje i funkcje
istniejące w zbiorze programu MATLAB. Załóżmy, że chcemy zdefiniować funkcję
f=xsinx.
Funkcja ta nie występuje w zbiorze funkcji programu MATLAB, lecz zbudowana jest
z funkcji standardowych. Definiujemy ją jako:
>> f=inline('x.*sin(x)')
f=
Inline function:
f(x) = x.*sin(x)
Zauważmy, że formuła funkcji zapisana jest jako łańcuch. Zauważmy także, że w zapi-
sie funkcji obowiązują reguły wynikające z traktowania zmiennych jako macierzy. Dlatego
znak mnożenia poprzedzono kropką, gdyż bez niej znak mnożenia interpretowany byłby jako
mnożenie macierzy. Jeżeli z góry zakładamy, że x będzie wyłącznie liczbą, znak kropi nie niej
potrzebny.
Po zdefiniowaniu funkcji f=f(x) możemy wyznaczać jej wartości dla dowolnej liczby x
lub dla wektora x. Przykładowo:
>> f(pi/2)
ans =
1.5708
37
3.5.5. Pętle
Pętle używane są do wielokrotnego powtarzania określonych obliczeń lub mówiąc
ogólniej – poleceń. Przykładowa, prosta pętla ma następującą formę:
>> for n=1:10
y(n)=n^2;
end
Każda pętla rozpoczyna się poleceniem for i kończy poleceniem end. Dla wyróżnienia
od innych poleceń program MATLAB zapisuje je kolorem niebieskim. Zapis pętli należy
rozumieć następująco: dla każdej liczby naturalnej n od 1 do 10 wykonaj działanie zapisane
wzorem umieszczonym niżej, przed poleceniem end. W naszym przykładzie polecenie polega
na podniesieniu do kwadratu kolejnych liczb naturalnych i utworzeniu z nich wektora y.
Wektor ten jest zapisany w pamięci i może być edytowany poza pętlą:
>> y
y=
38
1 4 9 16 25 36 49 64 81 100
Jak wiemy, zapis n=1:10 generuje wektor liczb naturalnych. W pętlach można definio-
wać inne wektory, których elementy tworzą ciągi monotoniczne. Zmienna n nie może być
wtedy używana do wytwarzania wektorów lub macierzy, gdy ich elementy oznaczane są wy-
łącznie liczbami naturalnymi. Można temu zaradzić w sposób pokazany w następującym
przykładzie:
>> for x=-5:0.5:5
n=2*x+11;
y(n)=x^2;
end
>> y
y=
Columns 1 through 7
25.0000 20.2500 16.0000 12.2500 9.0000 6.2500 4.0000
Columns 8 through 14
2.2500 1.0000 0.2500 0 0.2500 1.0000 2.2500
Columns 15 through 21
4.0000 6.2500 9.0000 12.2500 16.0000 20.2500 25.0000
Alternatywnym rozwiązaniem są następujące instrukcje:
>> for n=1:11
x=-5+(n-1)/2;
y(n)=x^2;
end
Zapisując pętlę należy zawsze pamiętać o stawianiu średników po każdej instrukcji.
Skutki nie zastosowania się do tej rady pokazuje wykonanie obliczeń w pierwszej z podanych
pętli, gdy pominiemy średnik:
>> for n=1:10
y(n)=n^2
end
y=
1
y=
1 4
y=
1 4 9
y=
1 4 9 16
y=
1 4 9 16 25
y=
1 4 9 16 25 36
y=
1 4 9 16 25 36 49
y=
1 4 9 16 25 36 49 64
y=
1 4 9 16 25 36 49 64 81
y=
1 4 9 16 25 36 49 64 81 100
Program zwraca kolejno budowane wektory, co jest nie tylko zbędne, lecz dodatkowo
zajmuje wiele czasu.
Powyższy przykład ilustruje ponadto mechanizm obliczeń w pętli. W każdym cyklu
tworzony jest nowy wektor o coraz to większej długości. Wymaga to wykonania szeregu ope-
39
racji, które zajmują dużo czasu, nawet, gdy pośrednie wyniki nie są edytowane. Dlatego obli-
czenia w pętlach wykonywane są względnie długo. Jeżeli jest to tylko możliwe staramy się
unikać obliczeń w pętlach i zastąpić je obliczeniami macierzowymi. Przykładowo ostatnią
pętle można i należy zastąpić następującymi instrukcjami:
>> n=1:10;
>> y=n.^2
y=
1 4 9 16 25 36 49 64 81 100
Jeżeli zastosowania pętli nie można uniknąć wówczas przed pętlą należy zdefiniować
najprostszą macierz lub wektor, w których będziemy zapisywać wyniki obliczeń w pętli.
Wymiary macierzy bądź wektora muszą być zgodne z liczbą wyników w pętli. Rozpatrywany
wyżej przykład powinien być zgodnie z tym zapisany jako:
>> y=zeros(1,10);
>> for n=1:10
y(n)=n^2;
end
Mechanizm działania programu jest wówczas odmienny, co ilustruje przykład wykony-
wania obliczeń w tej pętli (pominięto średnik).
>> y=zeros(1,10);
>> for n=1:10
y(n)=n^2
end
y=
1 0 0 0 0 0 0 0 0 0
y=
1 4 0 0 0 0 0 0 0 0
y=
1 4 9 0 0 0 0 0 0 0
y=
1 4 9 16 0 0 0 0 0 0
y=
1 4 9 16 25 0 0 0 0 0
y=
1 4 9 16 25 36 0 0 0 0
y=
1 4 9 16 25 36 49 0 0 0
y=
1 4 9 16 25 36 49 64 0 0
y=
1 4 9 16 25 36 49 64 81 0
y=
1 4 9 16 25 36 49 64 81 100
Program wpisuje do istniejącego obszaru pamięci kolejne wyniki obliczeń, a nie tworzy
coraz to nowe obszary, jak to miało miejsce w poprzedniej wersji pętli. Czas potrzebny na
wpisywanie danych do określonego obszaru pamięci jest znacznie krótsze. Oczywiście róż-
nice w czasie wykonywania obu wersji pętli przy tak małej liczbie operacji są niezauważalne.
Cierpliwy Czytelnik może osobiście przekonać się o sensowności tych wskazówek zmieniając
liczbę 10 na 10000 i pisząc różne wersje zamieszczonych wyżej programów.
Odmianą opisanych pętli jest pętla rozpoczynająca się poleceniem while (dopóki).
Struktura takiej pętli jest podobna do poprzedniej, a mianowicie:
>> while <relacja logiczna>
<instrukcja>
40
end
Pętla ta nie ma określonej liczby cykli i instrukcja wykonuje się dopóki relacja logiczna
jest spełniona. Oto przykład wyznaczania kolejnych liczb naturalnych:
>> y=0;
>> while y<3
y=y+1
end
y=
1
y=
2
y=
3
W pierwszym wierszu zadeklarowana jest wartość początkowa. W drugim wierszu
sprawdzana jest relacja logiczna y<3. Relacja ta jest prawdziwa, dla y=0,1,2. W trzecim wier-
szu zwiększana jest zmienna y o 1. W pierwszym cyklu mamy y=0+1=1, w drugim y=1+1=2 a
w trzecim y=2+1=3. Pętla przestaje działać, gdyż y<3 nie jest prawdziwe.
Poniżej podano przykład prostego programu do wyznaczania wartości x, przy której
funkcja sinπx przyjmuje wartość maksymalną. Dokładność wyniku wynosi 0.00001.
>> d=0; x=0;
>> while d>=0
d=sin(pi*(x+0.00001))-sin(pi*x);
x=x+0.00001;
end
>> x
x=
0.5000
Takie samo zadanie może być wykonane przez inną pętlę z wykorzystaniem polecenia
break. Polecenie to kończy obliczenia w pętli przed ich zakończeniem wskazanym w instruk-
cji obok for. Polecenie break powinno być poprzedzone instrukcją warunkową.
>> for x=0:0.00001:1
d=sin(pi*(x+0.00001))-sin(pi*x);
if d<=0
break
end
end
>> x
x=
0.5000
Pętle są używane do tworzenia wektorów, co już pokazano, a również do budowania
macierzy i tablic wielowymiarowych. Takie pętle zawierają pętle zewnętrzne i wewnętrzne.
Struktura takiej złożonej pętli jest następująca:
for m=1:M
<instrukcja>
for n=1:N
<instrukcja>
end
end
Instrukcja w zewnętrznej linii pętli jest opcjonalna. Prosty przykład pętli generującej
macierz pokazuje następujący przykład:
>> y=zeros(5,6);
41
Y(:,:,1) =
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
6 7 8 9 10
Y(:,:,2) =
4 5 6 7 8
5 6 7 8 9
6 7 8 9 10
7 8 9 10 11
Y(:,:,3) =
5 6 7 8 9
6 7 8 9 10
7 8 9 10 11
8 9 10 11 12
Tablica Y składa się z 3 macierzy o wymiarach 3x5. Wartość elementy tablicy jest sumą
numeru wiersza, kolumny i macierzy, co widoczne jest w podanym wyżej wydruku tablicy. Z
tablicy można utworzyć różne macierze po to, aby na nich wykonywać potrzebne operacje.
Mamy np.
>> A=Y(:,:,2)
A=
4 5 6 7 8
5 6 7 8 9
6 7 8 9 10
7 8 9 10 11
Macierz A jest macierzą o wymiarach:
>> size(A)
ans =
4 5
Niestety utworzenie macierzy, w której występują wiersze lub kolumny ze wszystkich
K tablic stwarza pewien problem. Pisząc bowiem:
>> B=Y(2,:,:)
B(:,:,1) =
4 5 6 7 8
B(:,:,2) =
5 6 7 8 9
B(:,:,3) =
6 7 8 9 10
otrzymujemy nadal tablicę o wymiarach
size(B)
ans =
1 5 3
Na tablicy B nie można wykonywać poznanych już operacji macierzowych. Zachodzi
więc potrzeba przekształcenia takiej tablicy w macierz. Można to uczynić wykorzystując na-
stępującą pętlę:
>> B=zeros(3,5);
>> for m=1:3
for n=1:5
B(m,n)=y(2,n,m);
end
end
>> B
B=
43
4 5 6 7 8
5 6 7 8 9
6 7 8 9 10
Rzeczywiście otrzymaliśmy macierz, gdyż
>> size(B)
ans =
3 5
Można do tego celu wykorzystać również funkcję reshape, która przekształca tablicę w
macierz o odpowiednich wymiarach. Składnię tej funkcji pokazuje przykład:
>> B=reshape(Y(2,:,:),3,5)
B=
4 7 6 9 8
5 8 7 6 9
6 5 8 7 10
a sprawdzamy jej skuteczność pisząc:
>> size(B)
ans =
3 5
44
4. GRAFIKA
4.1. Grafika dwuwymiarowa
4.1.1. Podstawowe funkcje graficzne
Z punktu widzenia obliczeń inżynierskich użyteczne jest szczególnie przedstawianie w
formie graficznej funkcji, wyników obliczeń i symulacji. Na ogół wystarcza do tego celu po-
sługiwanie się dwuwymiarowym układem współrzędny prostokątnych lub biegunowych. W
układach tych mogą być przedstawiane funkcje typu y=f(x) oraz płaskie figury geometryczne.
W programie MATLAB® mają one zwykle formę dwóch wektorów o równej długości, z któ-
rych jeden zawiera dyskretne wartości zmiennej niezależnej x, a drugi – dyskretne wartości
zmiennej zależnej y. Zajmiemy się najpierw graficzną reprezentacją tak rozumianych funkcji.
Do wykonywania wykresów we współrzędnych prostokątnych służą funkcję graficzne,
których podstawowy format jest następujący:
funkcja_graficzna(x,y,<parametry>)
Funkcja graficzna otwiera okno, w którym pojawi się wykres określony wektorem x,
wektorem y oraz parametrami. Parametry są opcjonalne i przy ich braku wykres wykonywany
jest przy parametrach domyślnych. Parametry umożliwiają wybór koloru wykresu, rodzaju
linii lub znaczników, z których jest wykonany. Lista tych parametrów jest długa i można je
znaleźć pisząc help plot. Przykładowy zapis funkcji graficznej wygląda następująco:
plot(x,y,’k*--‘);
gdzie parametry oznaczają: k –czarny kolor linii, * – oznaczenie punktów wykresu gwiazdką,
-- – wykres wykonany linią kreskową.
Format funkcji graficznych może być bardziej rozbudowany, ale ograniczymy się w
tym miejscu do formatu podstawowego.
Wektor wyznacza punkty na osi poziomej, którym przyporządkowane są elementy
wektora y. Inaczej mówiąc element wektora x(n) określa współrzędną x, a element y(n) –
współrzędną y punktu, przez którą przechodzi wykres. Charakterystyczną cechą grafiki pro-
gramu MATLAB® jest to, że elementy wektora x nie muszą być rozmieszczone równomier-
nie, a nawet nie muszą stanowić ciągu monotonicznego (rosnącego lub malejącego). Pominię-
cie w zapisie funkcji graficznej wektora x powoduje, że skalą x będzie ciąg liczb naturalnych
od 1 do N, gdzie N jest długością wektora y.
Jeżeli nie użyjemy specjalnych, dodatkowych funkcji graficznych, to zakres osi X i Y
program dobiera automatycznie.
Program MATLAB® oferuje następujące funkcje graficzne, których efektem jest wyko-
nanie wykresu. Są to:
plot – wykonuje wykresy linią łamaną, przerywaną lub znacznikami, a linia ta
przechodzi prze punkty wyznaczone przez wektory x i y
stem – wykonuje wykresy w formie próbek
stairs – wykonuje wykresy w formie schodkowej
bar – wykonuje wykresy w postaci słupków
polar – sporządza wykresy we współrzędnych biegunowych
Ograniczymy się tu do opisu funkcji plot, stem i polar, gdyż pozostałe mają mniejsze
znaczenie w zastosowaniach inżynierskich.
45
Funkcja plot jest używana głównie do prezentacji graficznej funkcji ciągłych, chociaż z
konieczności są to w programie numerycznym funkcje dyskretne. Przykładowo, funkcja sinus
jest funkcją ciągłą, lecz program MATLAB® wyznacza jej wartości w skończonej liczbie
punktów i na wykresie łączy je odcinkami linii prostej. Przy malej liczbie punktów wykres
jest widoczny jako linia łamana, co fałszuje rzeczywisty przebieg funkcji. Zwiększając liczbę
punktów i zagęszczając je uzyskujemy pożądany efekt ciągłości, czyli zbliżamy obraz gra-
ficznych do rzeczywistego przebiegu funkcji. Ilustruje to przykład pokazany na rys. 4.1.
Rys. 4.1. Wykresy funkcji sinus przy rożnej gęstości punktów zmiennej niezależnej, sporządzony
przez funkcję plot.
Funkcji stem używamy do prezentacji graficznej funkcji dyskretnych, zwłaszcza wtedy
gdy chcemy uwypuklić ich dyskretny charakter. Jeżeli przykładowo analizujemy lub symulu-
jemy system cyfrowy wykorzystujący próbki sygnałów, to dobrze jest zaznaczyć graficznie,
że wyniki mają postać dyskretną, a zatem są dostępne tylko w ograniczonej liczbie punktów
zmiennej niezależnej (np. czasu). Przebieg funkcji sinus przedstawiony przy użyciu funkcji
stem ma postać przedstawioną na rys. 4.2.
Rys. 4.2. Wykres funkcji w formie próbek wykonany przy użyciu funkcji stem.
46
Funkcję polar stosujemy wtedy, gdy chcemy zaprezentować graficznie funkcję, której
zmienną niezależną jest kąt. Na rys. 4.3. pokazano wykres funkcji sin(3x)/(3x), gdzie x jest
kątem wyrażonym w radianach.
Rys. 4.3. Wykres funkcji we współrzędnych biegunowych wykonany przez funkcję polar.
Na jednym rysunku można zamieścić większa liczbę krzywych używając następującego
formatu funkcji plot:
plot(x,y,<parametry>,u,v,<parametry>,…)
Zmienne (x,y), (u,v) i dalsze opisują parami kolejne krzywe umieszczone na wykresie. Za
każdą parą zmiennych można wpisać (opcjonalnie) łańcuch znaków określających parametry
danej krzywej, np.’g+-‘, co oznacza krzywą narysowaną linią ciągłą w kolorze zielonym z
punktami zaznaczonymi plusem.
Jeżeli zmienna y jest zespolona, to zapis plot(y) powoduje rysowanie krzywej
plot(real(y),imag(y)), czyli na osi poziomej umieszczane są współrzędne części rzeczywistej
liczby zespolonej y, zaś na osi pionowej – współrzędne części urojonej liczby zespolonej z.
Jest to klasyczny sposób prezentacji graficznej liczb zespolonych. Każdy inny zapis funkcji
plot, np. plot(x,y), gdzie y jest liczbą zespoloną powoduje pominięcie części urojonych i wyko-
nywany jest wykres plot(x,real(y)).
Wykonany rysunek chcemy najczęściej przechować w pamięci. W tym celu w oknie Fi-
gure No. 1 (lub o wyższym numerze) otwieramy menu File i wybieramy w nim Save As... Po-
woduje to otwarcie okna, które umożliwia zapisanie rysunku w pożądanym folderze i nadanie
mu nazwy.
Rysunek wykonany w programie MATLAB można skopiować do innego programu,
np. do jednego programu z zestawu Microsoft Office. W tym celu w oknie rysunku wybieramy
Edit i z wywołanego menu Copy Figure. Możliwe jest również wybranie sposobu kopiowania
rysunku. W menu Edit wybieramy wówczas polecenie Copy Options, co powoduje rozwinięcie
okna Preferenses. W oknie tym należy wybrać Figure Copy Template i w oknie Figure Copy
Template Preferenses wybrać program, do którego będą kopiowane rysunki, a następnie usta-
wić pożądane parametry. Po rozwiniecie menu Figure Copy Template pojawi się menu Copy
Options. W tym oknie wybieramy metodę kopiowania np. Bitmap oraz kolor tła rysunku, np.
Force White Background. Czynności te kończymy wciskając przycisk Apply.
Podaną wyżej procedurę wykonuje się jednokrotnie i powtarza tylko wtedy, gdy chce-
my zmienić jakieś parametry rysowania i kopiowania.
47
Po instrukcji Copy Figure rysunek znajduje się w schowku i jest dostępny w innych pro-
gramach. Np. programie Microsoft Word można go umieścić w dokumencie rozwijając menu
Edycja, wybierając Wklej specjalnie... i – przykładowo – Mapa bitowa. (Nie należy przejmować
się zbytnio informacją, że rysunek jako mapa bitowa zajmuje dużo miejsca w pamięci, gdy
program Microsoft Word dokonuje samoczynnie kompresji danych potrzebnych do odtwo-
rzenia rysunku).
Aktywne okno rysunku zamyka się poleceniem close. Wszystkie otwarte okna zamyka
instrukcja close all. Instrukcje tę warto umieścić na początku programu aby rysunki nie poja-
wiały się we wcześniej otwartych oknach rysunkowych oraz żeby nie mnożyć otwartych
okien rysunkowych przy kolejnych uruchomieniach programu.
Jeżeli na rysunku znajduje się większa liczba krzywych narysowanych różnym rodza-
jem linii lub różnym kolorem, wówczas przydatna jest legenda opisująca poszczególne
krzywe. Wykorzystuje się do tego celu następującą funkcję:
legend(‘nazwa pierwszej krzywej’, ’nazwa drugiej krzywej’, …,p)
gdzie p jest liczbą od -1 do 4 określającą położenie legendy na rysunku (domyślnie ustawione
jest 0, które umieszcza legendę w prawym górnym rogu).
Do opisu krzywych służy instrukcja funkcja text, której argumentami są pozycja tekstu i
łańcuch zawierający tekst:
text(xt,yt,’tekst’)
Współrzędne xt,yt odnoszą się do skal występujących na rysunku. Kilkukrotne użycie
funkcji text umożliwia naniesienie na rysunku w różnych miejscach dowolnych tekstów (naj-
częściej opisów krzywych).
Przy dużym zakresie zmiennych wygodnie jest sporządzać wykresy w skali logaryt-
micznej. Służą do tego celu trzy funkcje, którymi zastępujemy funkcję plot zachowując w
pełni jej format. Są to:
loglog(…) – obie osi w skali logarytmicznej o odstawie 10,
semilogx(…) – oś X w skali logarytmicznej, oś Y w skali liniowej
semilogy(…) – oś X w skali liniowej, oś Y w skali logarytmicznej.
Polecenie grid powoduje pojawienie się na rysunku siatki. Linie siatki występują w
punktach osi X i Y, które są opisane liczbami. Polecenie grid minor zagęszcza siatkę, a grid off
powoduje jej zniknięcie.
Funkcja plot otwiera pierwsze okno rysunkowe i łącznie z kolejnymi funkcjami powo-
duje wykonanie pożądanego wykresu. Polecenie figure otwiera drugie okno i w nim sporzą-
dzany jest rysunek według funkcji stem (lub innej) i dodatkowych, znajdujących się poniżej
instrukcji. W ten sam sposób można otwierać kolejne okna rysunkowe, które otrzymują ko-
lejne numery. Jeżeli funkcja plot, stem lub inne tego typu nie są poprzedzone poleceniem fig-
ure, to rysunek będzie wykonany w ostatnim otwartym oknie. Poprzedni rysunek będzie au-
tomatycznie usunięty.
Kolejnym rysunkom należy przypisać nazwę, jeżeli chcemy je zapamiętać. Sposób za-
pamiętywania rysunków podano wyżej.
Pierwszy sposób umieszczania na wspólnym rysunku kilku krzywych polega na omó-
wionym wyżej wykorzystaniu funkcji plot z wieloma argumentami. Druga metoda wykorzy-
stuje polecenie hold on. Umieszczenie tego polecenia w programie (lub w oknie Command
Window) po pojawieniu się okna rysunkowego powoduje, że kolejne rysunki będą nakładane
na istniejący. Oto przykład krótkiego programu rysującego dwie funkcje zmiennej zespolonej,
a mianowicie y=exp(j2x) oraz z=xexp(j2x).
x=0:0.001:1;
y=exp(i*2*pi*x);
plot(y,'k')
axis square
title('Funkcje zmiennej zespolonej')
xlabel('Re');ylabel('Im')
set(gcf,'color','white')
grid
z=x.*y;
hold on
plot(z,'k:')
legend('y','z')
Po uruchomieniu programu otrzymujemy wykresy pokazane na rys. 4.4.
Funkcja set(…) zmieniła tło obrzeża rysunku na biały; domyślnie jest obrzeże ma kolor
szary, co w tekście nie jest raczej korzystne. Funkcja set ma szerokie zastosowanie w grafice
programy MATLAB® i jej omówieniem zajmiemy się w dalszej części skryptu.
W jednym rysunku można umieścić kilka układów współrzędnych i wykreślić w każ-
dym z tych układów pewną liczbę krzywych. Służy do tego celu funkcja subplot, która w pod-
stawowym formacie ma trzy parametry:
subplot(m,n,p).
Parametr m wskazuje, w ilu wierszach maja być utworzone rysunku, a parametr n – w
ilu kolumnach. Liczba pól przeznaczonych na rysunki wynosi zatem m·n. Nie w każdym polu
musi być zamieszczony rysunek. Parametr p wskazuje, w którym polu ma znajdować się
określony rysunek. Rysunki są wykonywane według zasad obowiązujących dla pojedynczego
rysunku. Wybierając liczbę rysunków należy pamiętać, że ze zwiększaniem tej liczby maleje
powierzchnia przeznaczona na każdy z rysunków, co czyni je mniej czytelnymi. Poniżej
przedstawiono program sporządzający trzy rysunki w jednym oknie figure.
x=2*pi*(0:0.001:1);
ys=sin(x);
subplot(2,2,1); plot(x,ys)
title('sinus');xlabel('x');ylabel('ys')
axis([0 2*pi -1 1])
yc=cos(x);
subplot(2,2,2); plot(x,yc)
title('cosinus');xlabel('x');ylabel('yc');
axis([0 2*pi -1 1])
yt=tan(x);
subplot(2,2,3); plot(x,yt)
title('tangens');xlabel('x');ylabel('yt')
axis([0 2*pi -10 10])
Powyższy programu sporządza rysunek pokazany na rys. 4.5.
Rys. 4.5. Trzy wykresy funkcji umieszczone na jednym rysunku przy użyciu funkcji subplot.
51
W oknie tym istotne znacznie ma rozwinięcie etykiety Style, widoczne na rysunku. Do-
bieramy w nim styl linii, jej grubość i kolor. Linie można uzupełnić znacznikami (Marker Pro-
perties), których lista znajduje się w okienku Style: Po wybraniu znacznika dobieramy jego
rozmiar (Size:), kolor obramowania (Edge color:) oraz kolor wypełnienia (Face color:). Efekty
wyboru pokazywane są automatycznie w okienku Example.
Jeżeli na rysunku zaznaczymy lewym klawiszem myszy najpierw strzałkę w na pasku
narzędziowym, a potem wybrany obiekt (np. linię wykresu) i wybierzemy z menu Edit pole-
cenie Current Object Properties..., to otworzy się odpowiednie okno dotyczące tego obiektu. Są
to te same okna, które omówiliśmy wyżej.
Inny sposób zmieniania właściwości rysunku polega na użyciu myszki. Jeżeli po na-
prowadzeniu wskaźnika myszki wciśniemy jej lewy klawisz, to wybrany obiekt zostanie za-
znaczony. Po wciśnięciu prawego klawisza pojawia się okienko z listą funkcji i parametrów
właściwych dla danego obiektu. Wybranie Properties... powoduje otwarcie stosownego okna i
dalsze postępowanie nie różni się od opisanego wyżej. Dodatkowo z okna można wybrać:
Cut– usuwa wszystkie elementy rysunku i przechowuje je w schowku, z którego
mogą być odtworzone po wciśnięciu Paste
Copy – zachowuje element w schowku w celu jego ponownego użycia
Paste – umieszcza element znajdujący się w schowku na rysunku
Clear – usuwa zaznaczony obiekt z rysunku
W zależności od rodzaju zaznaczonego obiektu w oknie pojawia się lista parametrów,
których wartości można zmieniać z pominięciem okna otwieranego przez Properties. Np. w
wypadku linii można zmieniać jej grubość, styl i kolor.
W pasku narzędziowym znajduje się ikona oznaczona jako A, która służy do pisania
tekstu na rysunku. Po wciśnięciu tej ikony (jej tło staje się białe) naprowadzamy wskaźnik
myszy na miejsce, w którym ma być umieszczony tekst, a następnie przyciskamy lewy kla-
wisz myszy. Na pojawiającym się wtedy szarym prostokącie wpisujemy tekst. Formatowanie
tekstu odbywa się tak samo jak formatowanie innych elementów rysunku.
Na pasku narzędziowym rysunku znajdują się także inne ikony, które służą do rysowa-
nia strzałek, linii prostych oraz do powiększania, zmniejszania i obracania wybranych frag-
mentów rysunku. Po przyciśnięciu ikony rysowania strzałki na polu rysunkowym pojawia się
krzyżyk, który ustawiamy myszą w pozycji początku strzałki i po przyciśnięciu lewego klawi-
sza przeciągamy krzyżyk do pozycji końcowej (grot strzałki). Analogicznie rysuje się linie
proste.
Po wciśnięciu ikony powiększenia (oznaczoną +) naprowadzamy kursor myszy na kra-
niec obszaru rysunku, który ma być powiększony. Przeciągając następnie kursor do drugiego
krańca tego obszaru zaznaczamy pole rysunku ulegające powiększeniu. W momencie pusz-
czenia klawisza myszy zaznaczony fragment rysunku zajmuje całą przestrzeń między osiami.
Zmniejszenie powiększonego fragmentu rysunku uzyskuje się po wciśnięciu ikony oznaczo-
nej jako – , naprowadzeniu kursora myszy na pole rysunku i przyciskanie lewym klawiszem
myszy do czasu uzyskania pożądanego rozmiaru rysunku.
Obracanie rysunku jest wykorzystywane w grafice trójwymiarowej.
54
Jeżeli taką zmodyfikowaną macierz Cmm wstawimy jako argument funkcji colormap, to
zmieni się skala kolorów:
colormap(Cmm)
Można również w razie potrzeby skonstruować własną macierz Cm, zachowując wszak-
że jej strukturę, czyli liczbę kolumn równą 3.
Efekty wprowadzonych zmian można zobrazować używając instrukcji colorbar. Na ak-
tywnym rysunku (lub nowym, gdy nie ma rysunku) pojawia się pionowy słupek z naniesioną
aktualną paletą barw.
Program MATLAB® dysponuje szeregiem standardowych palet barw, które mogą być
użyte na rysunku. W celu wybrania odpowiedniej palety barw piszemy następujące instrukcje:
colormap jet – domyślna paleta barw używana na zamieszczonych wyżej rysunkach
colormap hot – ciepłe kolory od czarnego, poprzez czerwony do białego
colormap cool – zimne barwy od zielonego, poprzez niebieski do fioletowego
colormap gray – skala szarości
colormap(‘default’) – przywraca domyślną paletę barw
Poza wymienionymi można użyć także: autumn, bone, colortube, cooper, flag, hsv, pink,
prism, spring, summer i winter.
Każda tak zapisana paleta zawiera 64 kolory. Liczbę kolorów można zmniejszyć lub
zwiększyć w ramach danej palety pisząc np.
jet(10) lub hot(100).
Standardowa paleta zawiera teraz tylko 10 kolorów, a paleta hot - 100 kolorów. Powyż-
sze instrukcje można zapisać również w zwartej formie, jak np.:
colormap(hot(100))
Zmian palety kolorów można dokonywać ręcznie otwierając menu Edit, a w nim Color-
map… Otwiera się wtedy okno Colormap Editor, w którym można wybrać pożądaną paletę
barw. Należy jednak pamiętać, że ustawienia palety uzyskane tą metodą odnoszą się wyłącz-
nie do aktywnego rysunku. Preferowane jest ustawienie palet programowo, gdyż efekt jest
wtedy powtarzalny. Pożyteczne jest wykorzystywania okna Colormap Editor do eksperymen-
talnego doboru palety. Pisząc po wybraniu palety w Command Window instrukcję Cm=colormap
otrzymujemy macierz, którą można wykorzystać w programie.
Paleta barw jest wykorzystywana w ten sposób, że program MATLAB® automatycznie
przypisuje najniższy kolor z palety barw do najmniejszej wartości macierzy Z, a najwyższy
kolor – do największej wartości tej macierzy. Można jednak tę zasadę zmienić używając in-
strukcji caxis. Jest ona podobna do instrukcji axis, która ustala zakres skali wykresu. Składnia
tej funkcji ma postać:
caxis([cmin cmax])
gdzie cmin oznacza najmniejszą wartość macierzy Z, do której przypisany jest najniższy kolor
aktualnej palety barw zaś cmax – najwyższą wartość, do której jest przypasany najwyższy
kolor. Jeżeli zakres wartości macierzy Z zawarty jest w granicach cmin do cmax, to do wyko-
nania wykresu użyta zostanie tylko odpowiednia część pełnej palety barw. W przeciwnym
wypadku wartości macierzy Z mniejsze od cmin oznaczone zostaną kolorem odpowiadającym
cmin, a przekraczające cmax – kolorem przypisanym do cmax.
59
Rys. 4.11. Trójwymiarowy obraz funkcji Gaussa wykonany przy użyciu instrukcji surf, colormap,
caxis i colorbar.
Na pionowym pasku widoczna jest pełna paleta barw w tonacji zimnej (cool). Składa się
ona z 32 kolorów. Ponieważ Zmin<cmin, więc obszar powierzchni o wartościach mniejszych
60
od cmin=0.01 jest oznaczony najniższym kolorem z palety barw. Z drugiej strony Zmax<cmax,
a zatem nie jest wykorzystana pełna paleta barw.
Z
Y
X
elewacja
azymut
Standardowo, kąt azymutu wynosi –37.50, a kąt elewacji +300 i przy tak położonym
układzie współrzędnych wykonane są wszystkie, zamieszczone wyżej, rysunki.
Ustawienie układu współrzędnych zmienia instrukcja:
view(az,el) lub view([az,el])
gdzie az oznacza kąt azymutu (w stopniach), a el – kąt elewacji.
Położenie prostej, na której leży punkt obserwacji można również ustawić podając
współrzędne jednego z punktów prostej x,y,z:
view([x,y,z])
Instrukcja view(2) ustawia obserwatora na osi Z i uzyskujemy dwuwymiarowy obraz
przestrzeni, zaś instrukcja view(3) ustawia układ współrzędnych w standardowej pozycji.
61
Na pasku narzędziowym okna Figure znajduje się ikona w kształcie okręgu, która służy
do ręcznej zmiany położenia układu współrzędnych. Po wciśnięciu przycisku z tą ikoną na-
leży naprowadzić znacznik myszy na pole obrazu i - trzymając wciśnięty lewy klawisz –
przesuwać znacznik do momentu uzyskania pożądanego położenia układu współrzędnych.
Położenie obserwatora przy istniejącym ustawieniu układu współrzędnych można wyznaczyć
zapisując następującą funkcję:
[az,el]=view
Wartości te można wykorzystać w pisanym programie do pożądanego, niestandardo-
wego ustawienia układu współrzędnych.
Program MATLAB® dysponuje bardzo rozbudowanym zestawem narzędzi służących do
ustawiania położenia obserwatora względem układu współrzędnych, a także do ciągłej zmia-
ny tego położenia. Efekty działania tych narzędzi są podobne do funkcjonowania kamery fo-
tograficznej i filmowej. Nie ma tu miejsca na omawianie tych narzędzi, dlatego wspomnimy
jedynie o jednej z licznych możliwości, a mianowicie o pasku narzędziowym Camera Toolbar,
który rozwija się z menu View, znajdującym się w oknie Figure. Posługując się ikonami znaj-
dującymi się na tym pasku, Czytelnik może samodzielnie sprawdzić i wykorzystać możliwo-
ści programu MATLAB® w zakresie grafiki trójwymiarowej.
Instrukcja lighting służy do wyboru algorytmu, który jest stosowany przez program MA-
TLAB® do uzyskania efektów oświetlenia. Mamy cztery możliwości do wyboru:
– przypisuje odpowiedni kolor do każdej elementarnej płaszczyzny, z
lighting flat
których utworzona jest rysowana powierzchnia
lighting gouraud –interpoluje kolory wewnątrz płaszczyzn, co daje lepszy efekt
przy rysowaniu krzywych powierzchni
lighting phong – postępuje jak wyżej, przy czym interpolacja dotyczy każdego
piksela,
a więc rysowanie trwa dłużej.
lighting none – wyłącza źródło światła
Instrukcja material pozwala dobrać materiał, z którego zbudowana jest oświetlana po-
wierzchnia pod względem właściwości odbijających światło. Są to:
material shiny – materiał połyskliwy
material dull – materiał matowy
material metal - metal
material default – domyślny, automatyczny dobór materiału
axis([-2*pi 2*pi -4*pi 4*pi -0.5 1]) % Ustawienie zakresu osi wykresu
title('Funkcja dwóch zmiennych') % Tytuł wykresu
xlabel('x','position', [10.2 -5 -1.05]) % Opis osi wykresu i ustawienie położenia napisu
ylabel('y','position', [-5 15.5 -0.72])
zlabel('Z','position', [-5 15 1],'rotation',0)
view(-45,40) % Ustawienie kątów azymutu i elewacji obserwatora
colormap jet % Ustawienie palety barw
caxis([-0.5 1]) % Ustawieni wartości zmiennej Z dla najniżej
i najwyższej barwy
camlight(10,-5) % Ustawienie kątów azymutu i elewacji źródła światła
lighting phong % Określenie metody interpolacji barw
material shiny % Określenie materiału powierzchni
set(1,'color','white') % Ustawienie koloru obrzeża rysunku
X=
0 -1 -2 -3 -4 -5 -6
0 -1 -2 -3 -4 -5 -6
0 -1 -2 -3 -4 -5 -6
0 -1 -2 -3 -4 -5 -6
0 -1 -2 -3 -4 -5 -6
Y=
0 0 0 0 0 0 0
2 2 2 2 2 2 2
4 4 4 4 4 4 4
6 6 6 6 6 6 6
8 8 8 8 8 8 8
można je przedstawić jako funkcje dwóch parametrów, np. m,n : X(m,n),Y(m,n), Z(m,n), C(m,n).
Parametry m,n mogą być kątami we współrzędnych sferycznych lub kątem i promieniem we
współrzędnych cylindrycznych.
Zamieszczony niżej krótki program ilustruje sposób tworzenia obrazu trójwymiarowego
figury, która nie może być wyrażoną funkcją dwóch zmiennych. Jest to figura, która powstała
w wyniku obrotu funkcji x=25+z2 wokół osi Z. Pokazano ją na rys. 4.14.
theta=pi*(-20:20)/20;
h=(-5:10)';
X=(25+h.^2)*sin(theta);
Y=(25+h.^2)*cos(theta);
Z=h*ones(1,41);
colormap winter
surf(X,Y,Z)
Graphical User Interface). Narzędzie to tworzy rysunek w formie planszy, na której mogą
znajdować się przyciski, klucze, suwaki, listy parametrów, pola wykresów itp. które obsłu-
guje się myszą lub wpisuje dane z klawiatury. Skutkiem każdej zmiany nastaw jest wykona-
nie odpowiednich operacji i ekspozycja wyników w formie graficznej, numerycznej lub łań-
cuchów znaków. W sumie odpowiednio zaprojektowana plansza GUI przypomina płytę czo-
łową przyrządu pomiarowego, np. oscyloskopu.
Planszę graficznego interfejsu użytkownika projektuje się stosunkowo łatwo używając
środowiska GUIDE (ang. GUI Design Environment). Wybiera się mianowicie myszą potrzebne
elementy z menu znajdującego się na planszy projektowej i umieszcza na planszy GUI, która
będzie obsługiwana po napisaniu programu przez użytkownika. Efektem tych operacji poza
planszą z naniesionymi elementami jest specjalny program utworzony automatycznie przez
GUIDE z rozszerzeniem .m oraz rysunek z rozszerzeniem .fig. Oba skrypty można umieścić w
katalogu work lub utworzonym własnym folderze.
Utworzony program z rozszerzeniem .m należy nazwać i zapamiętać, a nadana nazwa
będzie jednocześnie nazwą funkcji i nazwą rysunku. Taki skrypt definiuje zatem nową funk-
cję, a konsekwencją tego jest to, że zmienne w ramach funkcji są zmiennymi lokalnymi (nie
występują poza funkcją).
Skrypt definiujący funkcję zawiera szereg instrukcji, które nie powinny być zmieniane
przez programistę (definiują one planszę z jej elementami) oraz pewną liczbę instrukcji zapi-
sanych wstępnie jako komentarze. Po usunięciu znaku % oraz po niezbędnych uzupełnieniach
posłużą one do wykonania pożądanych operacji realizujących zadania programu. Nie wszyst-
kie z tych instrukcji muszą być wykorzystane. Oczywiście, poza omawianymi instrukcjami
zachodzi z reguły konieczność wprowadzenia innych, potrzebnych instrukcji.
Omawiany tu program może współpracować z innymi programami zapisanymi jako od-
dzielne pliki z rozszerzeniem .m. Ponieważ program GUI jest funkcją, to występujące w nim
zmienne nie są widoczne w innych programach i na odwrót. Przekazywanie zmiennych z pro-
gramu GUI do innych programów i w kierunku odwrotnym odbywa się przez specjalną bazę
danych, w której zawarte są wszystkie parametry obiektów znajdujących się na planszy użyt-
kownika.
Ogólne informacje o graficznym interfejsie użytkownika zakończymy uprzedzeniem, że
przedstawione dalej omówienie obejmuje jedynie niewielki fragment jego możliwości. Może
jednakże być pomocne w pokonaniu pierwszych kroków opanowania tego bardzo użytecz-
nego narzędzia.
W pliku z rozszerzeniem .fig znajduje się program, który rysuje plansze GUI. Program
ten jest tworzony automatycznie przez narzędzie GUIDE. Każdorazowa zmiana naniesiona na
planszy projektowej powoduje stosowaną zmianę tego programu.
Z menu File wybieramy Save As... i wpisujemy nazwę pliku, która będzie jednocześnie
nazwą programu (funkcji) z rozszerzeniem .m. Po wciśnięciu Zapisz, pojawia się plansza z
nadaną właśnie nazwą i możemy przystąpić do umieszczania wybranych elementów na plan-
szy. Są one widoczne w lewej kolumnie rysunku. Na górze kolumny znajduje się strzałka,
która służy wyłącznie do oznaczania i wybierania elementów planszy. Pozostałe ikony przed-
stawiają kolejno:
Push Button – przycisk – wciśnięcie myszą tego przycisku powoduje jednokrotną
reakcję programu, np. uruchomienie określonej procedury,
Toggle Button– przełącznik dwustanowy – w stanie wciśniętym (podświetlonym)
realizuje pewną procedurę, a w stanie zwolnionym – inną
– przycisk dwustanowy – działa jak Toggle Button, lecz jest zwykle
Radio Button
używany w grupie i wtedy można spowodować, że włączenie jednego przycisku
powoduje wyłączenie pozostałych
Checkbox – przycisk dwustanowy – używany do wyboru pewnej akcji; zwykle
stosuje się kilka takich przycisków do wyboru jednej lub kilku niezależnych ak-
cji
– okienko tekstowe – służy do edycji tekstu emitowanego przez pro-
Edit Text
gram lub do wpisywania tekstu przez użytkownika
– okienko tekstowe – w oknie tym wpisuje się stałe teksty informa-
Static Text
cyjne; program nie reaguje na tekst
– suwak – przesuwanie musza manipulatora zmienia wartość przypisanej
Slider
do suwaka zmiennej
Frame – ramka – służy do obramowania zespołu elementów na planszy w celu
zaznaczenia ich związku funkcjonalnego
– przycisk wielostanowy – zawiera listę elementów (łańcuchów), z któ-
Listbox
rych można wybrać jeden lub kilka
Popup Menu – zestaw przełączników dwustanowych w formie listy funkcjonują-
cych jak przełączniki Toggle Button; zastępuje zestaw przełączników Radio Button
Axes – osie – wyznacza położenie i wielkość rysunku umieszczonego na planszy
Położenie i wielkość każdego elementu można zmieniać myszą. Do zmian innych pa-
rametrów elementu służy Property Inspektor, który otwiera się przez oznaczenie elementu le-
wym klawiszem myszy i wciśnięciu prawego klawisza. Otwiera się wówczas okno z użytecz-
nymi instrukcjami służącymi do usuwania, kopiowania, wklejania i wykonania innych opera-
cji odnoszących się do zaznaczonego elementu. Na liście znajduje się również napis Property
Inspector, którego wciśnięcie otwiera okno zawierające wszystkie parametry danego elementu.
Najczęściej nie ma potrzeby dokonywania większych zmian owych parametrów. Ograni-
czamy się zwykle do zmiany nazwy elementu (String), zmiany nazwy zmiennej przypisanej do
elementu (Tag), doboru koloru tła (BackgroundColor), koloru czcionki (ForegroundColor), wy-
sokości czcionki (FontSize) i kroju czcionki (FontName). Wszystkie wprowadzone zmiany są
automatycznie zapamiętane i obowiązują przy każdorazowym otwarciu rysunku.
69
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Outputs from this function are returned to the command line.
function varargout = example1_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Wszystkie wiersze są niezbędne i nie należy ich zmieniać i usuwać. Ostatni wiersz za-
wiera funkcję start_Callback, która reaguje na każdorazowe wciśnięcie przycisku START. Za-
uważmy, że nazwa tej funkcji zawiera tekst wpisany jako Tag w Property Inspector. Funkcje
takie o nadanych im nazwach pojawią się w programie, w którym wystąpią także inne ele-
menty na planszy GUI. Struktura funkcji jest stała i ma postać pokazaną w przykładzie. hObjet
jest uchwytem (identyfikatorem) danego obiektu, eventdata jest zarezerwowane dla dalszego
rozwoju GUI i nie jest obecnie używane, handles to zasób danych związanych z danym obiek-
tem. W strukturze handles umieszcza się dane, które będą widoczne poza funkcją.
W przypadku Push Button reakcją na wciśnięcie tego przycisku jest wykonywanie
wszystkich instrukcji zapisanych za function start_Callback(hObject, eventdata, handles).
Przykładowo, jeżeli do powyższego programu dopiszemy
x=1:10;
figure
stem(x)
to każdorazowe wciśnięcie przycisku START spowoduje pojawienie się kolejno numerowa-
nego rysunku zawierające dziesięć próbek o wartościach od 1 do 10.
Rys. 4.18. Plansza z przełącznikiem Toggle Button i oknem edycyjnym Edit Text.
niem do funkcji czas zdefiniowanej w następnym wierszu, nazwa parametru ‘string’ i wartość
tego parametru ts. W momencie wciśnięcia przełącznika START w oknie edycyjnym pojawia
się zatem 0.
Od tego momentu program odlicza czas, aż do chwili zwolnienia przełącznika START.
Wartość stan jest wtedy równa 0, a zatem realizowana jest instrukcja t=toc. Ta standardowa
instrukcja programu MATLAB zatrzymuje zegar i zwraca jego wartość. Wartość ta jest wy-
świetlana w polu edycyjnym w wyniku działania omówionych wyżej instrukcji.
Podany program ilustruje sposób wykorzystywania ważnych funkcji get i set. Pierwsza
z nich służy do pozyskiwania parametrów, zaś druga do ich wprowadzania. Inny sposób ich
użycia pokazuje następny przykład użycia okna edycyjnego. W jednym oknie będziemy wpi-
sywać zmienną x, a w drugim podamy wartość funkcji y=log(x). Zaprojektowaną planszę po-
kazano na rys. 4.19.
if stan==1
set(handles.fsin,'value',0)
set(handles.ftg,'value',0)
set(handles.fctg,'value',0)
x=handles.x;
y=cos(pi*x/180);
ys=num2str(y);
set(handles.y,'string',ys)
end
set(handles.y,'string',ys)
elseif stan==3
x=handles.x;
y=tan(pi*x/180);
ys=num2str(y);
set(handles.y,'string',ys)
else
x=handles.x;
y=1/tan(pi*x/180);
ys=num2str(y);
set(handles.y,'string',ys)
end
powiednią akcję. Wciśnięcie potem cos(2x) ponownie uruchamia obie akcje. Aby uniknąć
tego niekorzystnego efektu, akcję uruchamiamy dopiero po ustawieniu całej listy.
Element Axes umieszczony na planszy otwiera okno do rysowania wykresów. Można
dobrać jego położenie i rozmiar w ten sam sposób, jak pozostałych elementów GUI. Element
axes nie ma odzwierciedlenia w programie z rozszerzeniem .m. Wykonywanie wykresów po-
lega na wpisaniu do tego programu instrukcji plot, stem, surf itp. Wszelkie napisy, skale itp.
wykonują instrukcje zapisane za plot, stem, surf, mesh itp.
Na planszy można umieścić kilka rysunków. Instrukcje plot, stem i inne muszą być
wtedy poprzedzone adresem rysunku (osi). Jeżeli kolejne osi nazwane są automatycznie
axes1, axes2, ..., to program do umieszczania wykresów na kolejnych rysunkach ma następu-
jącą strukturę:
axes(handles.axes1)
plot(x,y)
axes(handles.axes2)
stem(x,y)
................
Program do wykreślania czterech funkcji zamieszczono poniżej.
varargout{1} = handles.output;
%Wyznaczanie funkcji
x=2*pi*(0:0.01:1)
y1=sin(x);
y2=cos(x);
y3=sin(2*x);
y4=cos(2*x);
Y=[y1;y2;y3;y4]; % Macierz zawierająca w czterech wierszach wartości funkcji
handles.x=x; % Zapis zmiennej x w strukturze handles
handles.Y=Y; % Zapis macierzy Y w strukturze handles
guidata(hObject, handles);
% Oprogramowanie Listbox
Za ostatnią linią standardowej części programu GUI, którą zapisano dla przypomnienia
w pierwszym wierszu, znajduje się szereg instrukcji wykonujących obliczenia wartości funk-
cji. Z wartości tych funkcji tworzymy macierz Y. Obliczeń dokonujemy w tym miejscu, aby
były wykonane jednokrotnie, po uruchomieniu programu. Umieszczenie ich w ramach jakiejś
funkcji spowodowałoby ich powtarzanie po każdej akcji związanej z tą funkcją.
Wyniki obliczeń umieszczono w strukturze handles, aby były dostępne w obrębie in-
nych funkcji.
Zmienna stan w oprogramowaniu Listbox jest wektorem o długości równej liczbie wy-
branych funkcji. Elementami tego wektora są liczby od 1 do 4, odpowiadające położeniu
funkcji na liści. Przy zaznaczeniu sin(x) i cos(2x) wektor stan = [1 4]. Wektor stan umiesz-
czamy w strukturze handles, aby można z niego skorzystać w ramach funkcji Push Button,
nazwanej tu start.
W ramach funkcji Push Button (start) realizowany jest wybór wykresów i ich wykreśla-
nie. Najpierw odczytujemy wektor stan, następnie znajdujemy jego długość, która jest po-
trzebna do ustalenia liczby operacji w pętli. W kolejnych dwóch wierszach pobieramy warto-
ści zmiennej x i macierz Y ze struktury handles.
Do umieszczania kilku wykresów na jednym rysunku służy zapisana dalej instrukcja
hold on. Aby uniknąć nakładania nowych wykresów na umieszczone wcześniej zapisano in-
strukcję reset(gca), która usuwa zawartość aktualnego rysunku (osi). Funkcja gca (skrót ang.
get current axes) zwraca uchwyt (adres) aktualnego rysunku (osi). W pętli odczytujemy ko-
lejne wartości wektora stan i rysujemy wykres wiersza wektora Y o odczytanym numerze.
Instrukcja hold on – jak wspomniano wyżej – powoduje rysowanie kolejnych wykresów na
tym samym rysunku.
Poza pętlą określamy zakres osi wykresów i oznaczamy oś poziomą jako x.
w przedziale -10n+10.
Na drugim rysunku wykres ten będzie powiększany wokół środka wykresu, czyli wokół
n=0.
Wartość parametru ‘Value’ funkcji slider_Callback zależy od położenia suwaka. Standar-
dowy zakres zmian wynosi od Min=0 (lewe położenie suwaka) do Max=1 (prawe położenie
suwaka. Wartości te można zmienić w Property Inspektor w wierszach Min i Max. Zmiany poło-
żenia suwaka można dokonywać przyciskając strzałki lub przesuwając myszą suwak (zmiana
precyzyjna) lub przyciskając myszą na puste pole (zmiana zgrubna). Standardowo zmiana
strzałkami lub suwakiem dokonywana jest z krokiem 1% zakresu, z zmian zgrubna z krokiem
10% zakresu. Można to zmienić wpisując inne wartości x, y w SliderStep w Property Inspector.
Położenie spoczynkowe suwaka wynosi standardowo 0 i można je zmienić wpisując inną
wartość parametru Value. W naszym przykładzie użyliśmy ustawień domyślnych (standardo-
81
wych) z wyjątkiem wpisania Max=0.9 i zmiany tła suwaka. Po tych zabiegach plansza ma
postać pokazaną na rys. 4.23.
n=-10:0.001:10;
y=sin(pi*(n+eps)).*cos(10*pi*n)./(pi*(n+eps));
handles.y=y;
guidata(hObject, handles);
axes(handles.axes1)
plot(n,y)
axes(handles.axes2) %Odwołanie do dolnego rysunku
plot(n,y) % Początkowa postać dolnego rysunku
Jeżeli po nazwie pliku umieści się wykaz zmiennych to tylko te zmienne zostaną zapi-
sane w pliku.
clear
x=1:4; y=x.^2; z= 1./x;
save proba x z
Poleceniem load proba ładujemy zmienne zapisane w pliku proba.mat do przestrzeni ro-
boczej programu MATLAB.
clear;
load proba
who %Sprawdzanie aktualnej zawartości przestrzeni roboczej
Program zwraca:
Your variables are:
x y
Zmienne są teraz dostępne w przestrzeni roboczej i mogą być odpowiednio przetwa-
rzane.
6.1. Wielomiany
Wielomian N-tego stopnia jest ciągłą funkcja jednej zmiennej o następującym zapisie:
WN ( x, a) a(1)xN a(2)xN1 ... a(n)xNn 1 ... a(N)x a(N 1)
Funkcja
r=roots(a)
wyznacza pierwiastki wielomianu. Dla podanego wyżej wielomianu, zdefiniowanego współ-
czynnikami a(n) mamy:
>> r=roots(a)
r=
0
-1.0000
2.0000
1.0000
88
gdzie r(n) są residuami, p(n) – biegunami funkcji, a K(s,k) – wielomianem stopnia M-N+1. Jeżeli
M=N-1, to wielomian K(s,k) nie występuje.
Jeżeli pewien n-ty biegun występuje U-krotnie, czyli p(n)=p(n+1)=…=p(n+U-1), wówczas
w powyższym wzorze mamy:
BM (s, b) r(1) r(n) r(n 1) r(n U) r(N U)
... ... ... K(s, k )
A N (s, a) s p(1) s p(n) [s p(n)] 2
[s p(n)] U s p(N U)
B 2 ( s) 6s2 46s 86
3
A 3 (s) s 12s2 47s 60
% GRAFIKA
% Operacje ograniczenia wykresu do wartości 10
P=W<10; % Macierz pomocnicza wyznaczająca elementy spełniające
nierówność
WP=W.*P; % Macierz wartości spełniających nierówność
R=W>=10; % Macierz pomocnicza wyznaczająca elementy spełniające
nierówność
WO=WP+R*10; % Macierz przeznaczona do reprezentacji graficznej
% Wykres
surf(res,ims,WO,'linestyle','none')
xlabel('re(s)');ylabel('im(s)')
camlight(10,-5)
lighting phong
X=
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
Y=
-2 -2 -2 -2
-1 -1 -1 -1
0 0 0 0
1 1 1 1
2 2 2 2
>> S=X+i*Y
S=
1.0000 - 2.0000i 2.0000 - 2.0000i 3.0000 - 2.0000i 4.0000 - 2.0000i
1.0000 - 1.0000i 2.0000 - 1.0000i 3.0000 - 1.0000i 4.0000 - 1.0000i
1.0000 2.0000 3.0000 4.0000
1.0000 + 1.0000i 2.0000 + 1.0000i 3.0000 + 1.0000i 4.0000 + 1.0000i
1.0000 + 2.0000i 2.0000 + 2.0000i 3.0000 + 2.0000i 4.0000 + 2.0000i
Po drugie, wartości funkcji w biegunach są równe nieskończoności, co uniemożliwia
sporządzenie wykresu. Obcięto więc funkcję na poziomie 10, co realizują instrukcje zamiesz-
czone w programie. Z przebiegu wykresu należy domyślać się, że występujące na nim „ko-
miny” dążą do nieskończoności.
Funkcja
[B,A]=residue(R,P,K)
zwraca wartości współczynników wielomianu w liczniku i w mianowniku, analogicznie jak
funkcja poly w odniesieniu do wielomianów.
W celu znalezienia przybliżonych położeń miejsc zerowy wykonujemy wykres tej funk-
cji, który pokazano na rys. 6.2.
92
0
dx03 =
4.4409e-016
Jak widać, dwa pierwsze miejsca zerowe zostały wyznaczone z pełną dokładności osią-
ganą w programie MATLAB zaś trzeci – z bardzo małym błędem.
Jeżeli chcemy zawęzić przedział, w którym poszukiwane jest miejsce zerowe, wtedy
zamiast liczby x0 podajemy granice przedziału, np.:
>> x01=fzero(y,[-1.1 -0.9])
x01 =
-1
Znając przebieg funkcji (np. z jej wykresu), można napisać program, który sam wyzna-
czy przybliżone położenie miejsc zerowych. Oto przykład takiego programu:
y=inline('x.^3-4*x.^2+x+6'); %definicja funkcji
x=-2:0.1:4; % wektor zmiennej x
yn=y(x); % wektor dyskretnej funkcji y
yu=yn<0; % wyznaczanie przedziałów, w których funkcja jest ujemna
yo=abs(diff(yu)); % różniczkowanie powyższej funkcji
no=find(yo); % numery przybliżonych miejsc zerowych
xo=x(no) % wartości przybliżonych miejsc zerowych
x01=fzero(y,xo(1)) % pierwsze miejsce zerowe
x02=fzero(y,xo(2)) % drugie miejsce zerowe
x03=fzero(y,xo(3)) % trzecie miejsce zerowe
Kolejne operacje na funkcji ilustruje rys. 6.3.
tej funkcji. Czym mniejszy jest odstęp między wartościami niezależnej zmiennej dyskretnej,
tym wynik sumowania jest bardziej zbliżony do wartości całki. Oto prosty przykład.
Obliczmy wartość następującej całki:
1
y sin(x )dx .
0
1
y sin(n / N) , gdzie n=1,2,3,…,N
N n 1
i(t) L
u(t) R
i(t) L C
d2 y1 R dy1 1
2
y1 0
dt L dt LC
Oznaczamy
dy1
y2
dt
Po podstawieniu tej zależności do równania różniczkowego otrzymujemy
dy 2 R 1
y2 y1 0
dt L LC
Powyższym równaniom nadajmy formę układu równań dostosowaną do wymogów
funkcji ode.
dy1
y2
dt
dy2 1 R
y1 y 2
dt LC L
Parametrom RLC należy nadać teraz wartości liczbowe. Dobierzemy je tak, aby często-
tliwość rezonansowa f0=10 KHz, a dobroć Q=5 Przyjmując dodatkowo, że R=1 , otrzymu-
jemy:
QR 5 4
L 10 [H]
2f0 2
oraz
1 1 5
C 10 [F]
( 2)2 f02L
Mamy wtedy
R 2 4 1
10 oraz ( 2)2108
L 5 LC
Po wstawieniu tych wartości do układu równań różniczkowych otrzymujemy:
dy1
y2
dt
dy2 2
( 2)2108 y1 104 y 2
dt 5
Kolejnym krokiem jest zdefiniowanie funkcji odefun. Funkcja ta musi być zapisana w
formie wektora kolumnowego, przy czym w pierwszym wierszu jest zdefiniowana funkcja
dotycząca pierwszego równania, w drugim – drugiego itd., jeżeli mamy więcej równań. W
zapisie funkcji należy używać oznaczeń y(1), y(2) ..., gdyż wyniki są zapisywane w macierzy y
i konieczne jest wskazanie miejsca usytuowania y1, y2 w tej macierzy.
Warunki początkowe muszą być zapisane w formie wektora kolumnowego; w pierw-
szym wierszu y1(0), a w drugim y2(0). Przyjmiemy, że prąd początkowy wynosi y1(0)=1 A, a
jego pochodna y2(0)=0.
Funkcję odefun, po jej nazwaniu, można zdefiniować jako funkcję z rozszerzeniem .m i
umieścić ją w katalogu work. Można także użyć funkcji inline, co uczynimy w tym przykła-
dzie. Program rozwiązujący nasze równanie różniczkowe ma wtedy następujący zapis:
101
Rys. 6.8. Przebieg prądu w szeregowym obwodzie RLC wymuszony prądem początkowym i(0)=1A.
W następnym przykładzie pokażemy, w jaki sposób można wyznaczyć przebieg prądu
w rozpatrywanym wyżej obwodzie, gdy jest on pobudzany napięciem sinusoidalnym u(t) o
częstotliwości f1=0.5f0 i amplitudzie U0=1 V. Napięcie to jest dołączane w momencie czasu t=0.
Obwód taki jest pokazany na rys. 6.9.
i(t) L C
u(t) R
Aby nadać mu formę równania używaną w funkcjach ode, należy obustronnie je zróż-
niczkować. Zakładając, że u(t)=U0sin(2f1t) oraz oznaczając i=y1 otrzymujemy:
d2 y1 R dy1 1 U
2
y1 2f1 0 cos( 2f1t ) .
dt L dt LC L
Dalej postępujemy, jak w poprzednim przykładzie. Oznaczając
dy1
y2
dt
i podstawiając nową zmienną do równia różniczkowego mamy:
dy2 1 R U
y1 y 2 2 0 cos( 2f1t )
dt LC L L
Dwa ostatnie równania tworzą układ równań różniczkowych, który można rozwiązać
używając funkcji ode. Zachowując wartości LC z poprzedniego przykładu i zmniejszając
wartość R czterokrotnie otrzymujemy ostatecznie:
dy1
y2
dt
dy2 2 4 (2)2 8
( 2)2108 y1 10 y 2 10 cos( 10 4 t )
dt 20 10
Przy zerowych warunkach początkowych program rozwiązujący niejednorodne równa-
nie różniczkowe przedstawia się następująco:
f=inline('[y(2);-(2*pi)^2*10^8*y(1)-2*pi* 10^4*y(2)/20+(2*pi)^2*10^8*cos(pi*10^4*t)/10]','t','y')
f=
Inline function:
f(t,y) = [y(2);-(2*pi)^2*10^8*y(1)-2*pi* 10^4*y(2)/20+(2*pi)^2*10^8*cos(pi*10^4*t)/10]
[T,Y]=ode23(f,[0 2*10^-3],[0;0]);
plot(T,Y(:,1),'k')
Rys. 6.10. Przebieg prądu w szeregowym obwodzie rezonansowym pobudzonym napięciem sinuso-
idalnym o częstotliwości różnej od częstotliwości rezonansowej.
103
Rys. 6.11. Przebieg prądu w szeregowym obwodzie rezonansowym pobudzonym napięciem sinuso-
idalnym o częstotliwości równej częstotliwości rezonansowej.
104
s(t)
ti t
skala=0:19;
stem(skala,s)
axis([0 20 0 4])
xlabel('n');ylabel('s(n)')
Impuls złożono z dwóch ciągów, a mianowicie z ciągu p zawierającego 10 próbek o
wartości 2 i z ciągu 10 próbek zerowych. Pokazano go na rys.
Zauważmy, że utworzony w ten sposób impuls prostokątny jest dyskretnym odpowied-
nikiem nieskończonej liczby analogowych impulsów prostokątnych, z których pobrano z
pewnym okresem 20 próbek. Jeżeli wiemy, że okres próbkowania wynosi Ts=1 ms, to zbiór
impulsów analogowych ulega znacznej redukcji. Nie mniej jest on nadal nieskończenie
liczny, gdyż zawiera wszystkie impulsy o czasie trwania spełniających nierówność: 9 ms
ti<10 ms.
W ten sam sposób można zapisywać w formie dyskretnej impulsy o różnych kształtach.
Pokażemy dla przykładu instrukcje generujące impuls trójkątny.
pn=(0:5)/5;
po=(4:-1:1)/5;
o=zeros(1,10);
s=[pn po o];
skala=0:19;
stem(skala,s)
axis([0 20 0 2])
xlabel('n');ylabel('s(n)')
107
Gdy pożądany ciąg ma być bardzo długi, to do jego generacji można wykorzystać pętlę.
Poniżej zamieszczone instrukcje generują falę prostokątną utworzoną z pojedynczego impulsu
prostokątnego s(n). Okres fali zawiera 20 próbek, a cały ciąg składa się z 10 okresów.
p=2*ones(1,10);
o=zeros(1,10);
s=[p o]; % Pojedynczy impuls prostokątny
s10=zeros(1,200); % Rezerwacja pamięci
for m=1:10;
s10(1+20*(m-1):m*20)=s-1 % Odjęcie 1 powoduje, że wartość średnia sygnału wynosi 0
end
skala=0:199; % Wykres
stem(skala,s10)
axis([0 200 –2 2]
xlabel(‘n’); ylabel(‘s10(n)’)
Zapis argumentu funkcji s10 powoduje, że wartości ciągu s o długości 20 próbek są
wpisywane w kolejnych cyklach na pozycje 1:20, 21:40, 41:60 itd.
t=-9.5:9.5;
s=2*rectpuls(t,9.3);
s = [0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0]
Ten sam sygnał analogowy może mieć, jak widać dwie różne reprezentacje dyskretne
nawet przy tej samej częstotliwości próbkowania.
Analogicznie działa funkcja tripuls. Funkcja square generuje falę prostokątna pokazaną
na rys. Różnica polega na tym, że argumentem funkcji square jest wektor, którego wartości są
podawane w radianach, analogicznie jak w funkcji sinus.
t=0:199;
s=square(2*pi*t/20);
Do generacji ciągu impulsów można użyć funkcji pulstran, której pełny opis znajduje się
pliku help pulstran. Omówimy tu tylko jedną, najbardziej użyteczną, wersję tej funkcji. Ma ona
następującą składnię:
pulstran(t,d,p)
Należy utworzyć wektor t, który zawiera numery próbek sygnału oraz wektor d, który
zawiera numery próbek wyznaczających okres powtarzania impulsu. Wektor p zwiera próbki
impulsu, który ma być powtarzany z okresem zadanym wektorem d. Ilustrują to przykład, w
którym wygenerujemy ciąg pięciu impulsów o zadanym kształcie i okresie próbkowania.
Okres próbkowania jest dowolny, ale ustalony.
t=1:100;
t=0:100;
d=(0:4)*20;
p=[0 1 2 3 2 1 0 -1 -2 -3 -2 -1 0];
s=pulstran(t,d,p);
Wykres ciągu próbek pokazano na rys. 7.5.
Jak wynika z zapisanych wyżej instrukcji i jest widoczne na rysunku, impuls ma dłu-
gość 13 próbek, a okres jego powtarzania zawiera 20 próbek. Rzeczywiste czasy otrzymu-
jemy mnożąc te liczby przez okres próbkowania Ts.
Ciąg próbek impulsu można wygenerować w dowolny sposób, np. korzystając ze stan-
dardowych funkcji typu rectpuls, ones, sin, exp itp.
Na zakończenie omawiania sygnałów impulsowych wspomnijmy, że impuls Diraca ge-
nerują instrukcje
s=zeros(1,N); s(1)=1
a impuls jednostkowy
s=ones(1,N)
gdzie N jest liczbą próbek analizowanego lub przetwarzanego sygnału.
sigma =
2.0018
wariancja=var(szum) % Wariancja
wariancja =
4.0071
Zgodnie z przewidywaniami, wartości estymatorów zbliżyły się znacznie do wartości
oczekiwanych. Wynika stąd praktyczny wniosek, że gdy chcemy w obliczeniach numerycz-
nych uzyskiwać wyniki zbliżone do teoretycznych, to należy generować szum o możliwie
dużej liczbie próbek.
Program MATLAB dysponuje funkcjami umożliwiającymi wyznaczanie Rozkładów
gęstości prawdopodobieństwa zmiennych losowych. Są to mianowicie funkcje hist i histc. Je-
żeli zmienna losowa (np. szum) dana jest wektorem x, wówczas funkcja
hist(x)
wyznacza histogram zmiennej losowej i wykonuje jego wykres. Działanie tej funkcji polega
na znalezieniu wartości minimalnej i maksymalnej zmiennej x i podzieleniu przedziału ogra-
niczonego tymi wartościami na 10 równych przedziałów. Następnie oblicza się ile wartości
zmiennej y mieści się w poszczególnych przedziałach. Wyznaczone w ten sposób liczby są
wartościami histogramu, pokazywanymi na rysunku. W tej najprostszej formie funkcją hist
jest mało użyteczna ze względu na małą liczbę przedziałów zmiennej x. Liczbę przedziałów
można zmienić pisząc:
hist(x,P),
gdzie P jest pożądaną liczbą przedziałów.
Zapisując funkcję hist w postaci:
[h,xn]=hist(x,P)
otrzymujemy wartości histogramu h oraz wektor xn. Zawiera on kolejne wartości środków
przedziałów, w których zliczane są wartości zmiennej losowej x mieszczące się w tych prze-
działach.
Podobnie działa funkcja histc, której składania jest następująca:
h=histc(x,xe)
Wektorem xe zapisuje się kolejne wartości krańców przedziałów, w których zliczane są
zawarte w nich wartości zmiennej losowej x.
Omówione wyżej funkcje umożliwiają wyznaczenie przybliżonych rozkładów gęstości
prawdopodobieństwa p(x). Jak wiadomo rozkład prawdopodobieństwa spełnia równanie:
p(x)dx 1 .
p( x )dx p(n)x 1 ,
n
1
h(n) 1 ,
N n
116
1
h(n) p(n)x ,
N n n
a stąd mamy:
1
p(n) h(n) .
Nx
Ponieważ x=(xmax-xmin)/P, więc ostatecznie otrzymujemy:
P
p(n) h(n) .
N( x max x min )
przekształcenia Fouriera dotyczy także sygnałów dyskretnych (lub ściślej – ciągów liczbo-
wych), jest okresowe, ale również dyskretne. Jak we wszystkich obliczeniach numerycznych,
dyskretna transformata Fouriera jest wyznaczania zawsze ze skończonej liczby próbek sy-
gnału (z ciągów o ograniczonej długości). Jeżeli nieograniczony sygnał ciągły jest próbko-
wany i do obliczenia dyskretnej transformaty Fouriera bierze się ograniczoną liczbę próbek,
to z oczywistych względów widmo dyskretne nie może zawierać informacji o pominiętych
fragmentach sygnału. Może zatem (lecz nie zawsze musi) różnić się od widma ciągłego wy-
znaczonego dla całego sygnału.
W programie MATLAB funkcja wyznaczająca dyskretne widmo X wektora x ma za-
pis:
X=fft(x)
a wartości wektora X wyznaczane są z następującego wzoru:
N
(n 1)(k 1)
X(k ) x(n) exp[ j2
n1
N
],
Funkcja o zapisie
Xm=fft(x,M)
zwraca widmo dyskretne ciągu x o długości N uzupełnionego zerami do długości M>N.
Funkcja o zapisie
xm=ifft(X,M)
wyznacza ciąg o długości M, który jest okresowym rozszerzeniem ciągu x.
Dla zilustrowania działania funkcji fft i ifft wyznaczymy dyskretne widmo impulsu pro-
stokątnego:
x=[1 1 1 1 1 0 0 0 0 0];
X=fft(x)
X=
5 1 - 3.0777i 0 1 - 0.7265i 0 1 0 1 + 0.7265i 0 1 + 3.0777i
>> x=ifft(X)
x=
1 1 1 1 1 0 0 0 0 0
Widzimy, że prążki widma są liczbami zespolonymi. Zauważamy ponadto pewną sy-
metrię w wartościach liczbowych prążków. Polega ona na tym, że „symetryczne” prążki są
względem siebie sprzężone (mają odwrotne znaki przy częściach urojonych). Potwierdza się
119
Pomijając prążek o numerze n=1 (składowa stała) i traktując prążek o numerze n=5 jako
„oś symetrii” widzimy, że część rzeczywista i moduł widma są parzyste, a część urojona i fa-
za – nieparzyste. Jest to stała własność widma dyskretnego obowiązująca dla wszystkich cią-
gów rzeczywistych. Można to zapisać jako:
X(m)=X*(N-k+2) k=2,...,N/2-1 dla N parzystych
lub X(m)=X*(N-k+2) k=2,...,(N+1)/2 dla N nieparzystych
Argumentami funkcji fft i ifft mogą być również ciągi zespolone i dla takich ciągów po-
wyższa własność nie obowiązuje.
W funkcjach fft i ifft liczba prążków widma jest ograniczona do liczby próbek N. Jeżeli
znieśli byśmy to ograniczenie i obliczali widmo dla prążków o numerach dodatnich i ujem-
nych aż do nieskończoności, to zauważylibyśmy, że widmo jest okresowe, a długość okresu
wynosi N. Można to łatwo sprawdzić wstawiając do wzory na transformatę dyskretną zamiast
k numer mN+k. Wyznaczane widma można zatem traktować jako jeden okres widma okreso-
wego. Widmo okresowe byłoby dyskretnym odpowiednikiem ciągłego widma sygnałów dys-
kretnych.
tem pogodzić się z faktem wystąpienia pewnych rozbieżności, które mogą być akceptowane
w obliczeniach inżynierskich.
Zmienną w omówionym wyżej widmie dyskretnym są numery prążków oznaczone li-
terą k. Należy w pierwszej kolejności pokazać związek pomiędzy numerem prążka, a rzeczy-
wistą częstotliwością sygnału. Przyjmijmy, że sygnał s(t) jest próbkowany z częstotliwością
Fs, czyli, że odstęp między sąsiednimi próbkami wynosi Ts. Transformatę Fouriera takiego
sygnału można zapisać jako:
S( f ) s(t) exp( j2ft)dt s[n 1)T ] exp[ j2f (n 1)T ]dt
s s
gdyż moment czasu t=0 odpowiada próbce o numerze n=1. Jeżeli sygnał zawiera tylko N pró-
bek, to powyższą całkę można zastąpić suma:
N
S( f ) t s(n) exp[ j2f (n 1)T ]
n1
s
Porównując oba wzory dochodzimy do wniosku, że powinna być spełniona równość ar-
gumentów funkcji wykładniczych. Po oczywistych uproszczeniach mamy więc:
k 1
fTs
N
lub
k 1
f (k ) Fs
N
Jest to zależność, która numerom prążków widma dyskretnego przypisuje rzeczywistą
częstotliwość sygnału próbkowanego z częstotliwością Fs. Maksymalna częstotliwość f(N) jest
równa:
N 1
f (N) Fs
N
Ponieważ maksymalna częstotliwość sygnału musi być mniejsza od Fs/2, więc numery
prążków odpowiadające dodatnim częstotliwościom widma muszą spełniać nierówność3:
N
k 1
2
Prążki widma o wyższych numerach odnoszą się do ujemnych częstotliwości widma
sygnału analogowego zgodnie ze wzorem:
N k 1
f (k ) Fs
N
3
Dla parzystych N należy przyjąć, że maksymalna wartość k=N/2+1.
121
Aby otrzymać widmo ciągłe we właściwej skali należy prążki widma dyskretnego po-
mnożyć przez t, czyli przez Ts, gdyż taki jest w skali częstotliwości odstęp prążków widma
dyskretnego.
Odległość między sąsiednimi prążkami widma dyskretnego (rozdzielczość widma) wy-
nosi:
Fs 1 1
f ,
N NTs t0
gdzie t0 jest czasem obserwacji sygnału, czyli czasem, w którym zbierane są jego próbki.
Zamieszczony poniżej program wyznacza widmo dyskretne impulsu prostokątnego o
czasie trwania T=10 ms i wysokości 2 V. Sygnał jest próbkowany z częstotliwością Fs= 1 kHz.
Czas obserwacji sygnału wynosi t0=200 ms. Sygnał impulsowy ma nieograniczone widmo, a
więc – ściśle rzecz biorąc – nie można wyznaczyć częstotliwości Nyquista. Wyniki muszą dać
jedynie przybliżony przebieg widma.
%DANE
T=10*10^-3; % Czas trwania impulsu
Fs=10^3; % Częstotliwość próbkowania
to=200*10^-3; % Czas obserwacji
V=2; % Amplituda
%GENERACJA SYGNAŁU
M=round(T*Fs); % Liczba próbek w impulsie
N=round(to*Fs); % Liczba próbek w czasie obserwacji
s=zeros(1,N); % Próbki zerowe
s(1:M)=2; % Próbki w impulsie
Na rys. 7.11 pokazano moduł dyskretnego widma impulsu. Na następnym rysunku wi-
doczna jest obwiednia modułu widma dyskretnego oraz widmo ciągłe tego impulsu, wyzna-
czone teoretycznie. Jak widać, występuje różnica pomiędzy obu widmami. Jest ona spowo-
dowana „przeciekiem” w widmie dyskretnym, a ten z kolei jest skutkiem nieograniczonego
widma impulsu prostokątnego. Różnica obu widma może być zmniejszana przez zwiększenie
częstotliwości próbkowania Fs. Jeżeli chcemy zachować rozdzielczość widma, to należy pro-
porcjonalnie zwiększyć liczbę próbek, czyli zachować czas obserwacji. W rozpatrywanym
przypadku jest to równoważne wstawieniu dodatkowych próbek zerowych.
Rys. 7.12. Moduł widma impulsu prostokątnego: a) obwiednia widma dyskretnego, b) widmo ciągłe.
123
którego t częstotliwość f0 jest znana. Można wtedy dobrać częstotliwość próbkowania i czas
obserwacji w taki sposób, aby widmo dyskretne było wiernym odzwierciedleniem widma
ciągłego sygnału o nieskończonym czasie trwania. Przyjmijmy mianowicie, że Fs=10f0 oraz,
że liczba próbek N obejmuje całkowitą liczbę okresów sygnału sinusoidalnego, np. N=4 T0/Ts =
4Fs/f0. Wyznaczymy widmo sygnału przy założeniu, że faza jest przypadkowa. Program
wyznaczający widmo dyskretne przedstawiono niżej.
%DANE
fo=100; % Częstotliwość sygnału [Hz]
Fs=10*fo; % Częstotliwość próbkowania [Hz]
fi=2*pi*rand(1,1) % Faza [rad]
so=1; %Amplituda
%OBLICZENIA
N=4*Fs/fo; % Liczba próbek
n=0:N-1; % Numery próbek
s=so*sin(2*pi*fo*n/Fs+fi); %Sygnał sinusoidalny
S=fft(s); % Widmo dyskretne
%WYKRESY
f=n*Fs/N; % Skala częstotliwości [Hz]
subplot(2,2,1);stem(f,real(S)); % Część rzeczywista widma
subplot(2,2,2);stem(f,imag(S)); %Część urojona widma
subplot(2,2,3);stem(f,abs(S)); % Moduł widma
subplot(2,2,4);stem(f,unwrap(angle(S))); % Faza widma
Na rys. 7.13 widoczne są poszczególne składowe widma dyskretnego w formie graficz-
nej używanej w programie MATLAB. Zamiast numerów próbek wstawiono jedynie rzeczy-
wistą skalę częstotliwości.
Widmo nieograniczonego sygnału ciągłego zawiera dwa impulsy Diraca o „amplitu-
dzie” zespolonej zależnej od fazy, występujące na częstotliwościach 100 Hz i – 100 Hz. Jak
widać, w widmie dyskretnym mamy główny prążek na częstotliwości 100 Hz i drugi prążek
na częstotliwości 900 Hz. Zgodnie z podaną wyżej interpretacją można uznać go jako prążek
występujący na częstotliwości –100 Hz. Przebieg fazy widma wynika z błędów obliczeń nu-
merycznych i nie powinien być w tym wypadku brany pod uwagę. Właściwą wartość przesu-
nięcia fazy występuje tylko na częstotliwości 100 Hz i 900 Hz
124
Rys. 7.17. Filtracja w dziedzinie częstotliwości: a) sygnał sinusoidalny z szumem, b) widmo tego sy-
gnału, c) widmo po filtracji, d) sygnał po filtracji.
Należy zauważyć, że sygnał po filtracji nie jest idealnym sygnałem sinusoidalnym, gdyż
nieznacznie zmienia się jego amplituda i faza. Wynika to z pozostawienia w widmie czterech
prążków szumu oraz wpływu szumu na amplitudę i fazę prążka widma o częstotliwości 51
129
Hz. Nie mniej, porównując sygnały z rysunków a) i d) widzimy zasadniczą poprawę sygnału
do szumu, uzyskaną dzięki zastosowaniu filtracji w dziedzinie częstotliwości.
Pożądaną charakterystykę filtru uzyskuje się przez dobór stałych M i P (rzędu filtru) i
parametrów a(m) i b(p).
Filtry dzielą się na dwie klasy, a mianowicie filtry ze skończoną odpowiedzią impul-
sową (SOI), (ang. Finite Impulse Response –FIR) i filtry z nieskończoną odpowiedzią impul-
sową (NOI), (ang. Infinite Impulse Response –IIR). W filtrach typu FIR wszystkie współ-
czynniki a(m) są równe zeru, a więc próbki sygnału wyjściowego y(n) są wyznaczane wyłącz-
nie z próbek sygnału wejściowego x(n). W filtrach typu IIR zarówno współczynniki a(m), jak
b(p) są różne od zera. W konsekwencji sygnał wyjściowy zależy od próbek sygnału wejścio-
wego i poprzednich próbek sygnału wyjściowego. W filtrach takich występuje zatem sprzęże-
nie zwrotne, co ma zasadniczy wpływ na ich funkcjonowanie.
Wymienione typy filtrów cyfrowych różnią się właściwościami, z których wymienimy
najważniejsze:
filtry IIR wymagają wykonania znacznie mniejszej liczby operacji niż filtry FIR dla
uzyskania funkcji przenoszenia o zbliżonych parametrach,
filtry IIR mają skłonności do wzbudzeń, czyli samoczynnej generacji niepożądanych
sygnałów, której to wady nie mają filtry FIR,
filtry IIR mają nieliniową charakterystykę fazową, zaś filtry FIR z natury mają
charakterystykę liniową.
Wybór typu filtru zależy od tego, które z wymienionych zalet i wad mają większe zna-
czenie w danym zastosowaniu.
Filtry cyfrowe IIR są na ogół odpowiednikami filtrów analogowych i mają podobne pa-
rametry (często lepsze) i podobne funkcje przenoszenie. W związku z tym noszą te same na-
zwy, jak ich pierwowzory analogowe. Program MALTAB dysponuje bardzo wygodnymi i
prostymi narzędziami do projektowani filtrów obu typów. Narzędzia takie mają formę funk-
cji, których parametrami są pożądane parametry filtrów, a zmiennymi wyjściowymi – współ-
czynniki a(m) i b(p) występujące w podanym wyżej wzorze. Liczba i znaczenie parametrów
zależy od rodzaju filtru. Pokażemy to na przykładach jednego filtru IIR i jednego filtru FIR.
Opis pozostałych filtrów Czytelnik znajdzie w Help programu MATLAB pisząc help <na-
zwa filtru>. Dla ułatwienia poszukiwań podamy niżej listę dysponowanych rodzajów filtrów.
130
% Generacja sygnału
M=T*Fs; % Liczba próbek sygnału
m=1:M; % Ciąg numerów próbek
s=so*sin(2*pi*fo*m/Fs); % Sygnał sinusoidalny
n=sigma*randn(1,M); % Szum
x=s+n; % Sygnał z szumem
%Projekt filtru
Wn=2*[600 1400]/Fs; % Wektor granic pasma przenoszenia filtru
[B,A]=butter(8,Wn); % Wektory współczynników filtru Butterwortha
% Filtracja
y=filter(B,A,x); % Filtracja sygnału z szumem
z=filter(B,A,s); % Filtracja sygnału sinusoidalnego
%Wykresy
skala=m*10^3*T/M;
subplot(2,2,1);plot(skala,s,'k');axis([0 10 -2 2]);xlabel( 't [ms]');ylabel('s')
subplot(2,2,2);plot(skala,x,'k');axis([0 10 -2 2]);xlabel( 't [ms]');ylabel('x=s+n)')
subplot(2,2,3);plot(skala,z,'k');axis([0 10 -2 2]);xlabel( 't [ms]');ylabel('z')
subplot(2,2,4);plot(skala,y,'k');axis([0 10 -2 2]);xlabel( 't [ms]');ylabel('y')
Wynikiem działania powyższego programu jest następujący rysunek.
Sygnał z szumem na wyjściu filtru znacznie różni się od sygnału wejściowego, co jest
efektem poprawy stosunku sygnału do szumu. Jest także opóźniony i ma stan nieustalony,
lecz dodatkowo zmienia się jego amplituda i faza. Efekt te nie zanika z upływem czasu, gdyż
jest skutkiem szumu, który pozostał po filtracji.
Poprawę stosunku sygnału do szumu uzyskaną dzięki filtracji można oszacować nume-
rycznie wprowadzając pewne zmiany i uzupełnienia w podanym wyżej programie.
%Dane
so=1; % Amplituda sygnału sinusoidalnego
fo=1000; % Częstotliwość sygnału sinusoidalnego [Hz]
Fs=20*fo; % Częstotliwość próbkowania [Hz]
T=10 % Czas obserwacji [s]
sigma=0.5 % Dyspersja szumu
% Generacja sygnału
M=T*Fs; % Liczba próbek sygnału
m=1:M; % Ciąg numerów próbek
s=so*sin(2*pi*fo*m/Fs); % Sygnał sinusoidalny
n=sigma*randn(1,M); % Szum
x=s+n; % Sygnał z szumem
%Projekt filtru
Wn=2*[600 1400]/Fs; % Wektor granic pasma przenoszenia filtru
[B,A]=butter(8,Wn); % Wektory współczynników filtru Butterwortha
% Filtracja
z=filter(B,A,s); % Filtracja sygnału sinusoidalnego
v=filter(B,A,n); % Filtracja sygnału sinusoidalnego
% Obliczenia
SNRx=var(s)/var(n) % Wejściowy stosunek sygnału do szumu
SNRy=var(z)/var(v) % Wyjściowy stosunek sygnału do szumu
b=SNRx/SNRy % Wskaźnik poprawy stosunku sygnału do szumu
p=Fs/(1400-600) % Teoretyczny wskaźnik poprawy stosunku sygnału do szumu
% Wyniki
SNRx =
2.0003
SNRy =
24.5071
p=
12.2516
P=
12.5000
7.6. Splot
Operacja splotu wykorzystywana jest w analizie systemów i układów liniowych w dzie-
dzinie czasu oraz w innych zastosowaniach. Jeżeli system lub układ opisany jest odpowiedzią
impulsową k(t), czyli odpowiedzią na impuls Diraca, to między sygnałem wejściowym x(t) i
sygnałem wyjściowym y(t) zachodzi zależność splotowa:
y( t ) k()x(t )d .
y( t ) k( )x( t )d .
0
n
y(n) k(m)x(n m) ,
m1
m<n
E4
R4
R45
J4
R1 R24 R34 E5
J5
U1=I1*R1
U12=I12*R(1,2)
U23=I23*R(2,3)
U24=I24*R(2,4)
U34=I34*R(3,4)
U35=I35*R(3,5)
U4=I4*R4
U45=I45*R(4,5)
U5=I5*R5
% Moc wydzielająca się na opornościach
P1=abs(U1*I1)
P12=abs(U12*I12)
P23=abs(U23*I23)
P24=abs(U24*I24)
P34=abs(U34*I34)
P35=abs(U35*I35)
P4=abs(U4*I4)
P45=abs(U45*I45)
P5=abs(U5*I5*R5)
%Sprawdzenie
P=P1+P12+P23+P24+P34+P35+P4+P45+P5 % Suma mocy wydzielających się na
opornościach
PD=E(1)*I1+E(4)*I4+E(5)*I5 % Suma mocy dostarczonych ze źródeł
if P==PD
'Wyniki prawidłowe'
else
'Błędy!'
end
W analogiczny sposób rozwiązuje się obwody prądu stałego metodą napięć węzłowych.
Pokażemy to na prostym przykładzie obwodu, którego schemat zamieszczono na rys. 8.2.
U1 G12 U2 G23 U3
J1 G1 G2 G3 J3
U=inv(G)∙J.
Podany niżej program oblicza napięcia węzłowe, prądy płynące przez poszczególne
przewodności oraz moc wydzielającą się w obwodzie i moc do niego dostarczoną z obu źró-
deł.
%DANE
%Przewodności w [S]
G1=1; G2=2; G3=3;G12=1;G23=2;
% Prądy w [A]
J=[2 0 -1]';
%OBLICZENIA
%Wartości macierzy
G=zeros(3,3);
G(1,1)=G1+G12;
G(1,2)=-G12;G(2,1)=G(1,2);
G(2,2)=G2+G12+G23;
G(2,3)=-G23;G(3,2)=G(2,3);
G(3,3)=G3+G23;
'Napięcia węzłowe'
U=inv(G)*J
'Wartości prądów'
I1=G1*U(1)
I12=G12*(U(1)-U(2))
I2=G2*U(2)
I23=G23*(U(2)-U(3))
I3=G3*U(3)
'Moce w przewodnościach'
P1=I1^2/G1
P12=I12^2/G12
P2=I2^2/G2
P23=I23^2/G23
P3=I3^2/G3
'Suma mocy w przewodnościach'
P=P1+P12+P2+P23+P3
'Suma mocy dostarczonych'
PD=abs(J(1)*U(1))+abs(J(3)*U(3))
Dla wartości przewodności i prądów źródeł podanych w powyższym programie, wyniki
obliczeń są następujące:
>> ans =
Napięcia węzłowe
U=
1.0811
0.1622
-0.1351
ans =
Wartości prądów
I1 =
1.0811
I12 =
0.9189
I2 =
0.3243
I23 =
0.5946
I3 =
-0.4054
ans =
Moce w przewodnościach
141
P1 =
1.1687
P12 =
0.8444
P2 =
0.0526
P23 =
0.1768
P3 =
0.0548
ans =
Suma mocy w przewodnościach
P=
2.2973
ans =
Suma mocy dostarczonych
PD =
2.2973
i(t) L
u(t) R
a stąd otrzymujemy:
U( j) U( j)
I( j) ,
R jL Z( j)
Stąd mamy:
U( j) U0 oraz i(t ) I( j)e jt .
I(j) jest zespoloną amplitudą prądu, którą można zapisać jako:
I( j) | I( j) | e j( j)
gdzie |I(j)| jest amplitudą prądu, a - przesunięciem fazy między prądem i napięciem.
Napiszemy teraz program, który wykreśli zależność amplitudy i fazy w analizowanym
układzie w funkcji częstotliwości, a wyniki przedstawimy na rys. 8.4. Przyjmiemy jak po-
przednio, że R=1k, L=10 mH. Jedynym problemem jest właściwy dobór zakresu częstotliwo-
ści i odstępu między ich wartościami. Dobra wskazówką jest tzw. 3-decybelowa częstotliwość
graniczna, której wartość wynosi:
L
fg
2R
Przyjmując przykładowo, że zakres skali częstotliwości wynosi 10fg i dzieląc go na 100
równych części mamy:
%DANE
R=10^4;
L=10^-2;
Uo=1;
%OBLICZENIA
fg=R/(2*pi*L) %Częstotliwość graniczna
f=0:5*fg/100:5*fg; % Skala częstotliwości
I=Uo./(R+i*2*pi*f*L); %Zespolone wartości prądu
Ia=abs(I); %Amplituda prądu
fi=angle(I)*180/pi; %Faza prądu
%WYKRESY
subplot(2,1,1);plot(f/fg,Ia,'k');xlabel('f/fg');ylabel('abs(I) [A]')
subplot(2,1,2);plot(f/fg,fi,'k');xlabel('f/fg');ylabel('faza [deg')
fg =
1.5915e+005
Mnożąc charakterystykę amplitudową prądu przez oporność R i dzieląc przez U0 otrzy-
mujemy napięciową funkcję przenoszenia, która ma identyczny przebieg, jak pokazana na
rys. 8.4 charakterystyka prądowa.
143
i(t) L C
u(t)
R
Zapisany niżej program wyznacza funkcję przenoszenia układu (admitancję) dla kilku
dobroci Q w funkcji znormalizowanej częstotliwości f/f0=/0. Funkcję tę znormalizowano
mnożąc ją przez R, w wyniku czego jest ona bezwymiarowa.
K=zeros(301,3);
for n=1:3
Q(n)=n^2;
f=0:0.01:3;
K(:,n)=1./(1+i*Q(n)*(f-1./f))';
end
plot(f,K,'k');xlabel('f/fo');ylabel('K(f/fo')
Funkcje przenoszenia obwodu (krzywe rezonansowe) pokazano na rys. 8.6.
C
J1
C1 G1 L1 C2 G2 L2 U2
1
gdzie
1
Y11 jC1 G1 jC
jL1
Y12 Y21 jC
1
Y22 jC 2 G 2 jC
jL 2
Jak wiadomo z teorii układów liniowych, napięcie U2 jest również sinusoidalne. Nie ma
zatem potrzeby wyznaczania jego przebiegu w czasie; wystarczy znajomość jego amplitudy
zespolonej U2(j). W miejsce J1(j) można wstawić amplitudę prądu o dowolnej wielkości, np.
J1=1 A, co nie wpływa na wynik obliczeń.
Rozpatrywany układ jest filtrem pasmowo-przepustowym. Elementy układu można do-
brać tak, aby filtr miał założoną częstotliwość środkową fo i pożądane pasmo przenoszenia B.
Jeżeli nie chcemy wyznaczać wartości elementów analitycznie, a zdać się wyłącznie na obli-
czenia numeryczne, konieczne jest wykonanie licznych prób i minimalizacja uzyskanych błę-
dów. W tym celu założymy na wstępie, że oba obwody rezonansowe są identyczne i mają
częstotliwości rezonansową równą częstotliwości środkowej filtru. Założymy także wstępnie,
że szerokość pasma przenoszenia pojedynczego obwodu rezonansowego jest równa połowie
szerokości pasma przenoszenia filtru B. Dodatkowo należy założyć wartość przewodności
obwodów rezonansowych G1=G2=G oraz podać wartość współczynnika k =2C/C1. Przy takich
założeniach obowiązują następujące zależności, wynikające ze znanych własności równole-
głych obwodów rezonansowych:
f0
Q dobroć obwodu rezonansowego
B
146
2f0C1
Q1 Q2=Q1
G1
G
C1 C2=C1
2B
kC 1
C
2
1
L1 L2=L1
( 2f0 )2 C 1
Przy takich założeniach program obliczający funkcję przenoszenia przedstawia się na-
stępująco:
%WPROWADZANIE DANYCH
fo=input('fo=');
B=input('B=');
G=input('G=');
k=input('k=');
%WYZNACZANIE WARTOŚCI ELEMENTÓW
C1=G/(pi*B);
L1=1/(C1*(2*pi*fo)^2);
C=k*C1/2;
%WYZNACZANIE ADMITANCJI
a=i*2*pi;
N=10^3;
K=zeros(1,N);
for n=1:N
s=a*(n-1)*2*fo/N+eps;
Y11=s*(C1+C)+G+1/(s*L1);
Y12=-s*C;
Y=[Y11 Y12;Y12 Y11]; %Macierz admitancji
%WYZNACZANIE FUNKCJI PRZENOSZENIA
U=inv(Y)*[1 0]'; %Rozwiązanie równania macierzowego
K(n)=U(2,1); % Funkcja przenoszenia
end
%WYZNACZANIE PARAMETRÓW FUNKCJI PRZENOSZENIA
P=abs(K)>0.707*max(abs(K));
PD=diff(P);
p=2*fo*find(PD)/N;
'Szerokość pasma przenoszenia [Hz]'
Bo=p(2)-p(1)
'Częstotliwość środkowa [ Hz]'
fc=(p(1,1)+p(1,2))/2
%WYKRES FUNKCJI PRZENOSZENIA
f=2*fo*(1:N)/N;
plot(f,abs(K),’k’)
Wpisując podane niżej wartości parametrów otrzymujemy wyznaczoną szerokość pa-
sma i częstotliwość środkową oraz wykres modułu funkcji przenoszenia, pokazany na rys.
8.8.
fo=1000
B=400
G=10^-3
k=0.8
ans =
Szerokość pasma przenoszenia [Hz]
Bo =
354
147
ans =
Częstotliwość środkowa [Hz]
fc =
893
y=real(ifft(Y)
Jako przykład znajdziemy odpowiedź napięciową UR(t) układu RL pokazanego na rys.
8.3 na pobudzenie napięciem U(t) w postaci impulsu prostokątnego o czasie trwania ti. Funkcja
przenoszenia obwodu jest równa:
R 1 1
K( j)
R jL 1 j / g 1 jf / fg
gdzie fg=R/2L.
Ponieważ funkcja przenoszenia jest nieograniczona, więc w celu zapewnienia dobrej
dokładności obliczeń przyjmiemy:
Fs 20fg
Widmo impulsu prostokątnego jest również nieograniczone. Czas trwania impulsu na-
leży dobrać tak, aby istotna część widma była mniejsza od połowy częstotliwości próbkowa-
nia. Mamy zatem następujący warunek:
2 1
t i
Fs 10fg
Należy teraz wyznaczyć liczbę próbek ni impulsu prostokątnego. Jest ona równa:
ni t iFs 40
Liczbę próbek N dobieramy tak aby była większa od czasu trwania impulsu, np.
N=5*ni=200. Umożliwia to napisanie następującego programu.
'Górna częstotliwość pasma przenoszenia układu RL [Hz]'
fg=input('fg=');
'Częstotliwość próbkowania [Hz]'
Fs=20*fg
'Czas trwania impulsu [s]'
ti=4/fg
ni=round(ti*Fs);
N=5*ni;
%Generacja impulsu
x=zeros(1,N);
x(1:ni)=1;
%Widmo impulsu
X=fft(x);
%Funkcja przenoszenia
k=1:N;
Kp=1./(1+i*(20/N)*(-N/2+k));
K=[Kp(N/2:N) Kp(1:N/2-1)];
%Wyznaczanie odpowiedzi układu
Y=X.*K;
y=real(ifft(Y));
150
%Wykresy
t=1000*(k-1)/Fs;
f=k*Fs/(10^3*N);
subplot(2,2,1); plot(t,x,'k');xlabel('t [ms]');ylabel('x(t)'); axis([0 10 -0.5 1.5])
subplot(2,2,2); plot(f,abs(K),'k');xlabel('f [kHz]');ylabel('|K(f)|');
subplot(2,2,3); plot(f,abs(X),'k');xlabel('f [kHz]');ylabel('|X(f)|');
subplot(2,2,4): plot(t,y,'k');xlabel('t [ms]');ylabel('y(t)');axis([0 10 -0.5 1.5])
Na rys. 8.9 przedstawiono wyznaczone przez powyższy program przebiegi sygnałów
oraz widmo impulsu i funkcję przenoszenia.
Rys. 8.9. Odpowiedź y(t) układu RL o funkcji przenoszenia K(f) na impuls prostokątny x(t).
a(l)s
l0
l
K( s) M
b(m)s
m0
m
1 s G
Z(s) , 1 (2)
C G 1 2C
s2 s
C LC
Jeżeli wzmocnienie układu aktywnego jest proporcjonalne do impedancji, należy zasto-
sować równoległy obwód rezonansowy i wtedy K(s)=KZ(s). Gdy wzmocnienie układu jest
proporcjonalne do admitancji, to należy zastosować szeregowy obwód rezonansowy i przyjąć
K(s)=KY(s).
Obwody pokazane na rys. 8.12 mają transmitancję
U2 ( s )
K( s) .
U1 (s)
I L C R I
(1) U
(2)
C G L U
C
(3)
L C
Uwej Uwyj (7)
R
Uwej R Uwyj
L
(4)
L R
Uwej R Uwyj (8)
C
Uwej Uwyj
R
(5)
C R
C
(9)
Uwej Uwyj
Uwej L Uwyj
R
(6)
L Uwyj
Uwej
s 1
K ( s) (3)
1 RC
s
RC
R 1 R
K ( s) (4)
L R L
s
L
1 1 1
K( s) (5)
RC 1 RC
s
RC
s R
K ( s) (6)
R L
s
L
Bieguny układów (7) do (9) są zespolone i sprzężone, a wartość bezwzględna części
rzeczywistej jest równa . Część urojona opisana jest podanymi wyżej wzorami dla obwodów
rezonansowych.
R
2L
R s
K ( s) (7)
L R 1
s2 s
L LC
L 1
K ( s) (8)
C R 1
s s
2
L LC
s2
K( s) (9)
R 1
s2 s
L LC
Bieguny wszystkich obwodów są jednakowe, a ich transmitancje różnią się stopniem
wielomianu w mianowniku i „wzmocnieniem”.
Dysponując podanymi zależnościami można wybrać właściwe obwody dla projektowa-
nego filtru. I tak przykładowo, filtr dolnopasmowy, którego zera i bieguny wyznaczono w
poprzednim punkcie, ma w mianowniku wartość stałą, dwie paru biegunów zespolonych i
jeden biegun rzeczywisty. Można go zatem zbudować z dwóch obwodów rezonansowych o
konfiguracji (8) oraz obwodu RL (4) lub RC (6). Obwody (4) i (6) są z tego punktu widzenia
równoważne (na ogół wybieramy w takiej sytuacji obwód RC).
W drugim przykładzie mamy w liczniku s5 oraz w 5 par biegunów zespolonych. Filtr
można zatem zbudować z 5 obwodów szeregowych, równoległych bądź o konfiguracji (7).
Najczęściej wybieramy obwody równoległe, choć nie jest to regułą.
W analogiczny sposób wybiera się konfigurację filtrów o innych funkcjach przenosze-
nia.
C=zeros(1,M);
L=zeros(1,M);
for n=1:M
L(n)=R./(2*s(2*n-1)); %Wyznaczanie pojemności
C(n)=1/(L(n)*(o(2*n-1).^2+s(2*n-1).^2)); %Wyznaczanie indukcyjności
end
'Częstotliwości rezonansowe [Hz]'
f=1./(2*pi*sqrt(C.*L))
'Indukcyjności [H] obwodów rezonansowych'
L
'Pojemności [F] obwodów rezonansowych'
C
if m==1
'Oporność obwodu RC'
Rrc=input('Rrc=');
'Pojemność [F] obwodu RC'
Crc=1./(R*s(N))
end
%SPRAWDZENIE
F=1:2*Fg;
w=i*2*pi*F;
wm=size(w);
Z=zeros(M,wm(1,2));
K=ones(1,wm(1,2));
for n=1:M
Z(n,:)=1./(C(n)*w.*(R+w*L(n)+1./(w*C(n)))); %Wartości impedancji obwodów
rezonansowych
K=Z(n,:).*K; %Wyznaczanie iloczynu transmitancji
end
if m==1
K=K.*(1./(1+w*Crc*R));
end
Ka=abs(K); %Wartości bezwzględne transmitancji
'"Wzmocnienie |Uwyj|/|Iwej|'
Kamax=max(Ka)
%WYKRESY
subplot(2,1,1);plot(F,20*log10(abs(Ka/Kamax)),'k')
axis([min(F) max(F) -80 10])
xlabel('f [Hz]');ylabel('20log(|K|/Kmax)')
hold on
subplot(2,1,2);plot(F,unwrap(angle(K)),'k')
xlabel('f [Hz]');ylabel('faza [rad]')
hold on
1.0e+005 *
-0.0354 + 1.2349i
-0.0354 - 1.2349i
-0.0991 + 0.9903i
-0.0991 - 0.9903i
-0.1432 + 0.5496i
-0.1432 - 0.5496i
-0.1589
k=
7.7503e+033
Częstotliwości rezonansowe [Hz]
f=
1.0e+004 *
1.9662 1.5840 0.9039
Indukcyjności [H] obwodów rezonansowych
L=
0.0028 0.0010 0.0007
Pojemności [F] obwodów rezonansowych
C=
1.0e-006 *
0.0232 0.1000 0.4440
Oporność obwodu RC
Rrc=100
Pojemność [F] obwodu RC
Crc =
3.1457e-006
"Wzmocnienie |Uwyj|/|Iwej|
Kamax =
1.0000
%ZAŁOŻENIA PROJEKTOWE
'Rząd filtru N'
N=input('N=');
'Dolna częstotliwość graniczna Fd [Hz]'
Fd=input('Fd=');
'Górna częstotliwość graniczna Fg [Hz]'
Fg=input('Fg=');
'Oporność w obwodach rezonansowych [om]'
R=input('R=');
%OBLICZENIA
W=2*pi*[Fd Fg]; %Pasmo przenoszenia
[z,p,k]=butter(N,W,'s'); %Zera i bieguny transmitancji
s=abs(real(p));
o=abs(imag(p));
C=zeros(1,N);
L=zeros(1,N);
for n=1:N
C(n)=1/(2*R*s(2*n-1)); %Wyznaczanie pojemności
L(n)=1/(C(n)*(o(2*n-1).^2+s(2*n-1).^2)); %Wyznaczanie indukcyjności
end
'Częstotliwości rezonansowe [Hz]'
f=1./(2*pi*sqrt(C.*L))
'Indukcyjności [H]'
L
'Pojemności [F]'
C
%SPRAWDZENIE
Fc=(Fd+Fg)/2; b=Fg-Fd;
F=Fc-2*b:Fc+2*b;
w=i*2*pi*F;
wm=size(w);
Z=zeros(N,wm(1,2));
K=ones(1,wm(1,2));
for n=1:N
Z(n,:)=1./(1/R+w*C(n)+1./(w*L(n))); %Wartości impedancji równoległych obwodów
rezonansowych
K=Z(n,:).*K; %Wyznaczanie iloczynu impedancji równego
transmitancji
end
Ka=abs(K); %Wartości bezwzględne transmitancji
'"Wzmocnienie |Uwyj|/|Iwej|'
Kamax=max(Ka)
%WYKRESY
subplot(2,1,1);plot(F,20*log10(abs(Ka/Kamax)),'k')
axis([min(F) max(F) -60 10])
xlabel('f [Hz]');ylabel('20log(|K|/Kmax)')
hold on
subplot(2,1,2);plot(F,unwrap(angle(K)),'k')
xlabel('f [Hz]');ylabel('faza [rad]')
fir1 131
A
fir2 131
abs 13 fircls 131
angle 13 fircls1 131
axis 47 firgauss 131
firls 131
B firrcos 131
fix 15
bar 44 flattopwin 126
barthannwin 126 floor 15
blackman 126 fmin 94
blackmanharris 126 fminbnd 94
bohmanwin 126 fmins 94
break 40 for 38
butter 131 format 12
freqs 132
C freqz 132
Callback 73 function 35
camlight 61 fzero 93
caxis 58
ceil 15 G
chebwin 126 gausswin 126
cheby1 131 gca 62
cheby2 131 gcf 62
clear 11 get 62
clear all 11 grid 48
close 11 guidata 75
close all 11 guide 66
colormap 57
conj 29 H
conv 137
CreateFcn 74 hamming 126
cremez 131 handles 72
cumsum 29 hann 126
hist 116
D histc 116
hold on 49
delete 11
det 24 I
diff 29
dir 10 if 33
ifft 119
E imag 13
inline 36
eleseif 33 input 17
ellip 131 intfilt 131
else 33 inv 23
end 33
eye 18 K
F kaiser 126
fft 119 L
fftshift 122
figure 48 legend 48
filter 133 lightangle 61
find 32 lighting 62
findobj 62 load 83
164
loglog 48 semilogx 48
semilogy 48
M set 50
sgolay 131
material 62
size 31
max 30
sound 85
maxflat 131 square 109
mean 30 stairs 44
mesh 56
std 30
meshgrid 64
stem 44
min 30
str2double 75
modulate 113 subplot 50
sum 29
N sur 56
nargin 36
nargout 36 T
num2str 73
text 48
nuttallwin 126
title 47
triang 126
O tripuls 109
ode 97 tukeywin 126
ones 18
open 9 U
openvar 20
uigetfile 85
P
V
parzenwin 126 var 30
plot 44 varargin 36
plot3 54
varargout 36
polar 44
view 60
poly 88
polyval 89
W
pulstran 110
wav 85
Q wavread 85
wavwrite 85
quad 96
what 11
quad8 96
which 10
while 40
R who 11
rand 19 whos 11
randn 19
real 13 X
rectpuls 109
xlabel 47
rectwin 126
remez 131
Y
reshape 43
residue 89 ylabel 47
roots 88 yulewalk 131
round 14
Z
S
zeros 18
save 10 zlabel 57
saveas 10